You are seeing the limits of precision when using a float in java. Its 32 bit precision is simply not sufficient for what you are using it for.
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
float: The float data type is a single-precision 32-bit IEEE 754 floating point. Its range of values is beyond the scope of this discussion, but is specified in the Floating-Point Types, Formats, and Values section of the Java Language Specification. As with the recommendations for byte and short, use a float (instead of double) if you need to save memory in large arrays of floating point numbers. This data type should never be used for precise values, such as currency. For that, you will need to use the java.math.BigDecimal class instead.
You can demonstrate the problem by changing the type of your number to a double. In that case your DecimalFormat.format() outputs the correct value because double has enough precision to hold the number you are working with.
final DecimalFormat df = new DecimalFormat("###,###,###,##0.00");
df.setMinimumFractionDigits(2);
df.setMaximumFractionDigits(2);
System.out.println(df.format(210103.6f));
=> 210.103,59
final DecimalFormat df = new DecimalFormat("###,###,###,##0.00");
df.setMinimumFractionDigits(2);
df.setMaximumFractionDigits(2);
System.out.println(df.format(210103.6d));
=> 210.103,60