error: cannot find symbol is javac saying it met a name it cannot resolve: a variable, method, class or package that, at that point in the code, does not exist as far as it can tell. The error always comes with three lines that tell you exactly what and where. Read those, and the cause is one of six, each with a two-line fix.
Reading the message#
Main.java:12: error: cannot find symbol
int total = calculateTotal(items);
^
symbol: method calculateTotal(List<Item>)
location: class Main
Line 12, the caret under the exact name, the symbol line saying what kind of thing and its name (and for methods, the argument types it looked for), and the location saying where it searched. Every case below is diagnosed from those three lines.
Cause 1: a typo or wrong case#
symbol: variable totalCount
location: class Main
The variable is called totalcount, or total_count, or count. Java treats those as four different names. Search the file for the symbol from the message; if it is not there exactly as spelt, that is the bug. Editors underline these in red before you compile, which is a reason to fix red squiggles as they appear rather than at the end.
Cause 2: a missing import#
symbol: class ArrayList
location: class Main
Classes outside java.lang must be imported. ArrayList, List, HashMap, Scanner, LocalDate and everything else in the standard library needs an import line:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
IDEs fix this with a keyboard shortcut. From the command line, look the class up and add the import. Java 25’s module imports, import module java.base;, bring in the whole standard library at once for scripts and quick work.
Cause 3: the symbol is in another file that did not compile#
Compiling Main.java alone when it uses Item from Item.java:
javac Main.java # cannot find symbol: class Item
javac *.java # compile them together
javac -d out src/**/*.java # or with a proper source tree
javac finds other classes only if they are given on the command line, already compiled on the classpath, or in the source path. With a build tool this is handled; by hand, compile everything together.
Cause 4: scope#
for (int i = 0; i < 10; i++) {
int square = i * i;
}
System.out.println(square); // cannot find symbol: variable square
A variable declared inside braces exists only inside them. Declare it before the block if it is needed after. The same applies to variables declared in an if branch, a try block, or a method: a method’s local variables are invisible to other methods, which is where fields come in.
Cause 5: wrong method signature#
symbol: method add(String)
location: variable numbers of type List<Integer>
The method exists but not with those argument types. Here, a List<Integer> has no add(String). The symbol line shows the types the compiler saw; compare them with the method’s declaration. Also common: calling an instance method on a class name, or a static method on an instance, and calling a method that exists on a subclass through a variable typed as the parent.
Cause 6: a dependency or module is missing#
symbol: class ObjectMapper
location: class JsonService
The class comes from a library. Either it is not declared in the build, or the build has not downloaded it, or the IDE’s view of the project is stale.
mvn dependency:tree | grep jackson # is it there at all?
mvn clean compile # a fresh build outside the IDE
./gradlew build --refresh-dependencies
If the command-line build succeeds and the IDE still shows the error, reload the project in the IDE. If the command-line build fails too, add the dependency to pom.xml or build.gradle. With Java modules, a class in another module also needs a requires line in module-info.java.
Java version mismatch#
symbol: method toList()
location: interface Stream<String>
A method that exists in newer Java compiled with an older one. Stream.toList() arrived in Java 16, records in 16, List.of in 9, and so on. Check javac -version and the release or source setting in the build. The error appears on Java 25 code compiled by a build tool still configured for 11 or 17.
Questions people ask#
Is this the same as ClassNotFoundException?
No. Cannot find symbol is a compile-time error. ClassNotFoundException and NoClassDefFoundError happen at runtime when a class was present at compile time and is missing when the program runs, usually a classpath difference between build and run.
The IDE shows no error but the build fails.
The IDE and the build tool have different views of the classpath or the Java version. Trust the build; reload the project so the IDE matches it.
Why does it say “location: class Main” when the symbol is in another class?
Location is where the compiler was looking from, not where the symbol should be. It searched from Main and did not find it, which points at import, classpath or scope.
Can package names cause it?
Yes: a file whose package declaration does not match its folder, or a class referenced with the wrong package prefix. The symbol line says package in that case.
Where to go next#
- Java not working in VS Code — when the editor is the source of the error.
- Java basics — scope, imports and classes from the start.
- Building a complete Java project — the build tool that handles dependencies.