Java: Error: Could not find or load main class X

Quick answer

Almost always a classpath or working-directory mismatch. From the directory that contains your top-level package folder, run:

java -cp <classes-dir> <fully.qualified.ClassName>

Not a bare class name, and not from inside the package's own folder. If you're running a jar instead, see Fix 3 below — the message you'd get there is different.

The exact error string

$ java Main
Error: Could not find or load main class Main
Caused by: java.lang.ClassNotFoundException: Main

The Caused by line is the real diagnostic: this is a ClassNotFoundException at the JVM's own bootstrap step, before your program has run a single line. javac compiling your source without complaint tells you nothing about whether this specific java invocation can find the resulting .class file — the two are entirely separate tools with no shared awareness of each other's working directory or paths.

Why this happens

java looks for Main.class on the classpath — by default, the current working directory plus anything passed via -cp/-classpath or the CLASSPATH environment variable. If your class declares a package, the JVM expects to find it at a path matching that package under one of those classpath roots — com/example/Main.class under a directory that's on the classpath, not Main.class sitting by itself. Get either the directory or the class name wrong and the class simply isn't where the JVM looked.

Fix 1 (fastest): match your working directory to your classpath

Say Main.java declares package com.example; and you compiled it to an out/ directory:

out/
  com/
    example/
      Main.class
# ❌ wrong directory, wrong (unqualified) class name
$ cd out/com/example
$ java Main
Error: Could not find or load main class Main
Caused by: java.lang.ClassNotFoundException: Main

# ✅ classpath root, fully package-qualified name
$ cd out
$ java com.example.Main
Hello from Main!

Hello from Main! (or whatever your program prints) appearing is the success signal — there's no separate "loaded successfully" message, the JVM just runs your main method. Two mistakes stack in the broken example above: running from inside the package folder instead of the classpath root, and dropping the package prefix from the class name. Either one alone is enough to trigger this error.

If you compiled with javac directly rather than a build tool, the same rule applies to -d: use javac -d out src/com/example/Main.java to get this exact layout in the first place.

Fix 2: explicit classpath with -cp

Running from an arbitrary directory works too, as long as you point -cp at the classes root explicitly:

$ java -cp out com.example.Main
Hello from Main!

# multiple classpath entries (JARs and directories), separated by
# `:` on Linux/macOS or `;` on Windows:
$ java -cp "out:libs/gson-2.11.0.jar" com.example.Main        # Linux/macOS
$ java -cp "out;libs/gson-2.11.0.jar" com.example.Main        # Windows

This is the form most build tools and IDEs generate under the hood — if the IDE-generated command works but your manual one doesn't, diff them for exactly this: a missing -cp entry or a wrong separator character for your OS.

Fix 3: running a jar (different message if the manifest is missing)

A runnable jar needs a Main-Class entry in its manifest. Note this produces a different error message if the manifest itself is the problem — don't confuse the two:

# jar built WITHOUT a Main-Class manifest entry:
$ java -jar app.jar
no main manifest attribute, in app.jar
# ← this is a DIFFERENT error, not "Could not find or load main class"

# ✅ build with the manifest entry (Maven shade/assembly plugin,
#    Gradle `jar { manifest { attributes 'Main-Class': ... } }`,
#    or a hand-written MANIFEST.MF passed to `jar cfm`)
$ java -jar app.jar
Hello from Main!

If you land here searching for "could not find or load main class" but your actual message was "no main manifest attribute", you're in the right general area but the fix is different: add Main-Class: com.example.Main to the jar's manifest, not a classpath change.

Fix 4: default (unnamed) package classes

A class with no package declaration lives in Java's "default package" and is invoked without any qualification — but the classpath rule still applies exactly the same way:

# Main.java has NO package declaration
$ javac Main.java          # produces Main.class in the same directory
$ java Main                # ✅ works — you ARE already at the classpath root

One Windows-specific trap: some filesystems are case-insensitive, so a folder named Main and a class named main can silently coexist locally and then fail the moment the same project builds on a case-sensitive filesystem (Linux CI, macOS in its default configuration for newer volumes). Keep class names and their file/folder names cased consistently regardless of what your local OS tolerates.

Fix 5: the Java Platform Module System (Java 9+)

If your project is modular (has a module-info.java), invocation needs --module-path and -m instead of a plain classpath:

$ java --module-path out -m com.example.app/com.example.Main

Mixing the two invocation styles — passing -cp to a project that expects --module-path, or vice versa — produces this same "could not find or load" error, because the JVM is looking in the wrong kind of path entirely for a modular build.

Three lookalike errors, disambiguated

MessageWhat it meansFix
Could not find or load main class (this page)Class never located on the classpathFix classpath / working directory / class name
no main manifest attribute, in app.jarJar found and opened, but no Main-Class declaredAdd Main-Class to the manifest
UnsupportedClassVersionErrorClass found and opened, but compiled for a newer JDKRaise the runtime JDK or lower the compile target

Debugging checklist

Frequently Asked Questions

How do I fix 'Error: Could not find or load main class'?

Run java from the classpath root — the directory that contains your top-level package folder — using the fully package-qualified class name, not a bare class name and not the .class file's own directory. For a class declared package com.example; that compiled to out/com/example/Main.class, run java -cp out com.example.Main from the directory containing out/, not from inside out/com/example/.

Why does my program compile fine but fail to run with this error?

javac only cares about your source files and produces .class files wherever you tell it to. It has no concept of how you'll later invoke java. The class name, package, and classpath you pass to java are a completely separate, unchecked step — so a compile that succeeds says nothing about whether your run command matches where the class actually landed.

What is the difference between 'Could not find or load main class' and 'no main manifest attribute'?

"Could not find or load main class" comes from java ClassName (or -cp) when the JVM can't locate that class on the classpath at all. "no main manifest attribute, in app.jar" is a completely different message from java -jar app.jar, meaning the jar was found and opened fine, but its META-INF/MANIFEST.MF doesn't declare a Main-Class. The fix for the second is adding Main-Class to the manifest, not a classpath change.

Is 'Could not find or load main class' the same as UnsupportedClassVersionError?

No, and the distinction matters for diagnosis. "Could not find or load main class" means the .class file was never located. UnsupportedClassVersionError means the JVM found and opened the file, then rejected it because it was compiled for a newer Java version than the one running it — a completely different problem with a completely different fix (raise the runtime JDK or lower the compile target).

Why does this happen only in my IDE but not from the terminal, or vice versa?

The IDE's run configuration has its own idea of the working directory and output/classes folder, independent of what a terminal command does. A stale run configuration pointing at an old output path, or a module misconfiguration after a project restructure, produces this error in the IDE even when the equivalent terminal command with the correct classpath works fine — and the reverse is just as common after an IDE auto-fixes its own config.

More Java & backend errors

Browse the full reference for Java, Go, and Rust errors — exact message, cause, and fix.

All Error References Java: ClassNotFoundException / NoClassDefFoundError Java: UnsupportedClassVersionError
About the author

Pasindu Ishan is a software developer based in Sri Lanka. He builds privacy-first developer tools at JSON Dev Tools.