frohoff/ysoserial · error · IOException

couldn't find

Error message

couldn't find '${file}'

What it means

ClassFiles.classAsBytes() loads a class's resource (the .class file, as produced by classAsFile) via the ClassLoader and throws this IOException when getResourceAsStream returns null — i.e. the class file is not on the classpath of the loader that loaded ClassFiles itself. This happens when generating ysoserial payloads for classes not present in ysoserial's classpath.

Solutions

  1. Add the jar/module containing the target class to ysoserial's runtime classpath (e.g. java -cp ysoserial.jar:target-lib.jar ...).
  2. Verify the resource exists: ClassFiles.class.getClassLoader().getResource(ClassFiles.classAsFile(clazz)) returns non-null before calling classAsBytes.
  3. Ensure the same ClassLoader loads both ClassFiles and the target class; avoid cross-classloader class references in shaded/isolated environments.
  4. If shading, keep ysoserial's original package structure so classAsFile() paths still resolve.

Example fix

// before
byte[] bytes = ClassFiles.classAsBytes(com.example.OutOfCpClass.class); // throws
// after
String res = ClassFiles.classAsFile(com.example.OutOfCpClass.class);
if (ClassFiles.class.getClassLoader().getResource(res) == null) {
    throw new IllegalStateException("Add the jar containing " + res + " to the classpath");
}
byte[] bytes = ClassFiles.classAsBytes(com.example.OutOfCpClass.class);
Defensive patterns

Strategy: try-catch

Validate before calling

public static void requireClassResource(Class<?> clazz) throws IOException {
    String file = ClassFiles.classAsFile(clazz);
    if (ClassFiles.class.getClassLoader().getResource(file) == null) {
        throw new FileNotFoundException("Class resource not on classpath: " + file + " — add its jar to the runtime classpath");
    }
}

Type guard

public static boolean isClassOnClasspath(Class<?> clazz) {
    return ClassFiles.class.getClassLoader().getResource(ClassFiles.classAsFile(clazz)) != null;
}

Try / catch

try {
    byte[] bytes = ClassFiles.classAsBytes(clazz);
} catch (IOException e) {
    if (e.getMessage().startsWith("couldn't find")) {
        throw new IllegalStateException("Target class file missing from classpath: " + e.getMessage()
            + " — add the containing jar to -cp", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling ClassFiles.classAsBytes(SomeClass.class) where SomeClass was loaded by a parent/child loader whose resource path ('ysoserial/...' style .class path) is not resolvable by ClassFiles.class.getClassLoader(), or where the class came from generated/dynamic bytecode with no backing resource.

Common situations: Embedding ysoserial in an application and passing application classes not on the same classpath; shading/uber-jar packaging that drops or renames class resources; trying to serialize classes from a separate module/jar not on the runtime classpath; OSGi or app-server classloader isolation hiding the resource.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of frohoff/ysoserial@218bcffcaa (2026-09-12). Data as JSON: /api/errors/a19e48c11547d169. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/ysoserial/payloads/util/ClassFiles.java:31

		String str;
		if (clazz.getEnclosingClass() == null) {
			str = clazz.getName().replace(".", "/");
		} else {
			str = classAsFile(clazz.getEnclosingClass(), false) + "$" + clazz.getSimpleName();
		}
		if (suffix) {
			str += ".class";			
		}
		return str;  
	}

	public static byte[] classAsBytes(final Class<?> clazz) {
		try {
			final byte[] buffer = new byte[1024];
			final String file = classAsFile(clazz);
			final InputStream in = ClassFiles.class.getClassLoader().getResourceAsStream(file);
			if (in == null) {
				throw new IOException("couldn't find '" + file + "'");
			}
			final ByteArrayOutputStream out = new ByteArrayOutputStream();
			int len;
			while ((len = in.read(buffer)) != -1) {
				out.write(buffer, 0, len);
			}
			return out.toByteArray();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
	
}

View on GitHub (pinned to 218bcffcaa)