---
title: "How do I use UTF-8 in Java .properties files with ResourceBundle?"
description: "Since Java 9 `PropertyResourceBundle` reads `.properties` files as UTF-8 and falls back to ISO-8859-1 when the bytes are not valid UTF-8. On Java 8 the files are ISO-8859-1, so use `\\uXXXX` escapes or load them through a `ResourceBundle.Control` with a UTF-8 reader."
category: localization-files
date: 2026-10-09
canonical: https://localizely.com/i18n-questions/localization-files/how-do-i-use-utf-8-in-java-properties-files-with-resourcebundle/
---

# How do I use UTF-8 in Java .properties files with ResourceBundle?

On Java 9 and later, save the file as UTF-8 and nothing else is needed: `PropertyResourceBundle` reads `.properties` files as UTF-8 by default. On Java 8 and older the file is read as ISO-8859-1, so every character outside Latin-1 must be a `\uXXXX` escape, or you load the file yourself with a UTF-8 reader.

[JEP 226](https://openjdk.org/jeps/226) changed the default in JDK 9. The stream is decoded as UTF-8; if a `MalformedInputException` or `UnmappableCharacterException` occurs, the bundle resets and re-reads the whole stream as ISO-8859-1. That fallback keeps old escaped files working, and it is also why a file saved as Windows-1252 loads without an error but shows wrong characters: its bytes are not valid UTF-8, so the whole file is read as Latin-1. To make decoding strict, start the JVM with `-Djava.util.PropertyResourceBundle.encoding=UTF-8` (or `ISO-8859-1`); the file is then read in that encoding only and an invalid sequence throws. Other values are ignored, and the property is read once when the class initializes, so set it on the command line. Details are in the [`PropertyResourceBundle`](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/PropertyResourceBundle.html) Javadoc.

On Java 8 the `PropertyResourceBundle(InputStream)` constructor requires ISO-8859-1. The `native2ascii` tool turned UTF-8 files into `\uXXXX` escapes at build time; it was removed in JDK 9. The alternative that keeps the files readable is a `ResourceBundle.Control` that opens the resource with a UTF-8 reader and uses the `PropertyResourceBundle(Reader)` constructor, which has no encoding limitation:

```java
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Locale;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;

public class Utf8Control extends ResourceBundle.Control {
    @Override
    public ResourceBundle newBundle(String baseName, Locale locale, String format,
                                    ClassLoader loader, boolean reload)
            throws IllegalAccessException, InstantiationException, IOException {
        if (!"java.properties".equals(format)) {
            return super.newBundle(baseName, locale, format, loader, reload);
        }
        String resourceName = toResourceName(toBundleName(baseName, locale), "properties");
        try (InputStream stream = loader.getResourceAsStream(resourceName)) {
            if (stream == null) {
                return null;
            }
            return new PropertyResourceBundle(new InputStreamReader(stream, StandardCharsets.UTF_8));
        }
    }
}
```

```java
ResourceBundle bundle = ResourceBundle.getBundle("messages", Locale.GERMAN, new Utf8Control());
```

Drop the control once you are on Java 9 or later: the default already does the right thing, and `getBundle` with a `Control` throws `UnsupportedOperationException` in named modules.

Related settings:

- `java.util.Properties.load(InputStream)` still reads ISO-8859-1 on every Java version. If you read properties files directly, use `load(Reader)` with a UTF-8 `InputStreamReader`.
- Spring's `ResourceBundleMessageSource` and `ReloadableResourceBundleMessageSource` default to ISO-8859-1; call [`setDefaultEncoding("UTF-8")`](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/support/AbstractResourceBasedMessageSource.html#setDefaultEncoding(java.lang.String)). Spring Boot's auto-configured `MessageSource` uses `spring.messages.encoding`, which defaults to UTF-8.
- Set the editor to save `.properties` files as UTF-8. In IntelliJ IDEA that is Settings | Editor | File Encodings | Default encoding for properties files, which defaults to ISO-8859-1.

More on the format itself: [Java properties file](/java-properties-file/).

Source: https://localizely.com/i18n-questions/localization-files/how-do-i-use-utf-8-in-java-properties-files-with-resourcebundle/
