Fix java.lang.ExceptionInInitializerError When Static Field Initialization Fails in Java

intermediateโ˜• Java2026-05-04| Java 8+, any OS (Windows/Linux/macOS), any JVM-based project (Maven, Gradle, Spring Boot, plain Java)

Error Message

java.lang.ExceptionInInitializerError at com.example.MyClass.<clinit>(MyClass.java:15) Caused by: java.lang.NullPointerException
#java#static#initializer#classloader#exception#debug

The Error

Your app crashes at startup before doing anything useful. The console shows:

java.lang.ExceptionInInitializerError
	at com.example.MyClass.<clinit>(MyClass.java:15)
Caused by: java.lang.NullPointerException
	at com.example.MyClass.<clinit>(MyClass.java:12)

Three things tell you what happened:

  • ExceptionInInitializerError โ€” the JVM could not finish loading a class.
  • <clinit> โ€” that's the class initializer. A static block or static field assignment blew up.
  • Caused by โ€” the actual problem. Here it's a NullPointerException, but it could be anything: IllegalArgumentException, IOException, or something from your own code.

Why This Happens

The first time the JVM loads a class, it runs every static initializer in declaration order โ€” inline field assignments first, then static { ... } blocks. If any of them throws an unchecked exception (or an Error), the JVM wraps it in ExceptionInInitializerError and permanently marks the class as broken.

Here's the nasty part: every subsequent attempt to use that class โ€” even inside a catch block โ€” throws NoClassDefFoundError. You'll see a cascade of failures that all trace back to one bad static initializer. Fix the source, not the cascade.

Common Triggers

  • Reading a system property or env variable that is null at startup, then immediately calling a method on it
  • Calling a method on a static object that was never initialized
  • Parsing a hardcoded string (a date format, a number) that turns out to be malformed
  • Loading a file or classpath resource that doesn't exist when the class is first loaded
  • Two classes referencing each other's static fields at load time (circular initialization)

Step-by-Step Fix

Step 1 โ€” Read the Right Part of the Stack Trace

Ignore the ExceptionInInitializerError line at the top. Scroll to Caused by and find the line number in your source file.

Caused by: java.lang.NullPointerException
	at com.example.MyClass.<clinit>(MyClass.java:12)

Open MyClass.java, jump to line 12. That's where the damage is.

Step 2 โ€” Identify the Failing Static Code

Two patterns account for most cases:

// Pattern 1: inline static field
public class MyClass {
    // System.getenv("DB_URL") can return null โ€” calling .trim() on null crashes immediately
    private static final String DB_URL = System.getenv("DB_URL").trim();
}

// Pattern 2: static block
public class MyClass {
    private static final Connection conn;
    static {
        conn = DriverManager.getConnection(DB_URL); // throws if DB_URL is null
    }
}

Step 3 โ€” Add a Null or Error Guard

Validate the value before using it. A descriptive error message saves you 20 minutes of debugging later:

public class MyClass {
    private static final String DB_URL;

    static {
        String url = System.getenv("DB_URL");
        if (url == null || url.isBlank()) {
            throw new IllegalStateException(
                "Environment variable DB_URL is not set. " +
                "Please configure it before starting the application."
            );
        }
        DB_URL = url.trim();
    }
}

Throwing IllegalStateException from a static block still produces ExceptionInInitializerError. But now the Caused by message says exactly what's missing โ€” no guessing required.

Step 4 โ€” Move Initialization Out of Static Context

Static initializers run once, silently, before your app can even catch anything. File reads, network calls, and resource loading don't belong there. Lazy initialization is safer:

// Before: static init that can throw at load time
public class ConfigLoader {
    private static final Properties props = loadProperties(); // crash happens here, before main()

    private static Properties loadProperties() {
        // reads config.properties โ€” throws IOException if missing
    }
}

// After: defer to first use, handle errors explicitly
public class ConfigLoader {
    private static Properties props;

    public static synchronized Properties getProps() {
        if (props == null) {
            try {
                props = loadProperties();
            } catch (IOException e) {
                throw new RuntimeException("Failed to load config.properties", e);
            }
        }
        return props;
    }
}

Step 5 โ€” Break Circular Static Dependencies

Class A references B.PREFIX. Class B references A.NAME. When the JVM loads A first, B hasn't initialized yet โ€” so B.PREFIX is null. The fix is a third class that owns the shared constants:

// Problematic: A loads B, B loads A โ€” one sees null
public class A {
    public static final String NAME = B.PREFIX + "_A";
}
public class B {
    public static final String PREFIX = A.NAME + "_B";
}

// Fix: extract to Constants โ€” no circular dependency
public class Constants {
    public static final String PREFIX = "APP";
}
public class A {
    public static final String NAME = Constants.PREFIX + "_A";
}
public class B {
    public static final String NAME = Constants.PREFIX + "_B";
}

Step 6 โ€” When It's a Third-Party Class Failing

Sometimes <clinit> points to a library, not your code. That usually means a missing configuration file or classpath resource. Read the full Caused by chain:

// Example: Log4j can't find its config
java.lang.ExceptionInInitializerError
	at org.apache.logging.log4j.LogManager.<clinit>(LogManager.java:...)
Caused by: java.lang.IllegalStateException: No log4j2 configuration file found

The fix here is dropping log4j2.xml onto your classpath โ€” not changing any Java code.

Verify the Fix

  • Recompile and rerun. The ExceptionInInitializerError should be gone.
  • If you added a guard that throws IllegalStateException, test it: unset the env variable and confirm you see your custom message rather than a bare NPE.
  • Run your unit tests. Any test that was silently failing to load the class will now pass โ€” or give a readable failure message.
# Smoke test after fix
$ java -cp . com.example.Main
# Expected: app starts cleanly, no ExceptionInInitializerError

# Test the guard with a blank env var
$ DB_URL= java -cp . com.example.Main
# Expected: IllegalStateException: Environment variable DB_URL is not set.

Quick Reference

  • Read Caused by, not the top line โ€” ExceptionInInitializerError is a wrapper; the real exception is underneath.
  • Null-check env vars and system properties before calling any method on them inside a static block.
  • Keep file I/O and network calls out of static initializers โ€” defer them to methods that can be retried and caught.
  • Circular class dependencies โ€” extract shared constants to a dedicated class to break the cycle.
  • NoClassDefFoundError after the first failure is a follow-on symptom, not a separate bug. The static initializer that failed first is the one to fix.

Related Error Notes