quarkusio/quarkus · error · RuntimeException
String too large to record: ${param}
Error message
String too large to record: ${param} What it means
Recorded String parameters are emitted as JVM ldc constants, which are limited to 65535 UTF-8 bytes by the class file format. Quarkus rejects any String longer than that at recording time because it could not produce valid bytecode for it.
Source
Thrown at core/deployment/src/main/java/io/quarkus/deployment/recording/BytecodeRecorderImpl.java:697
ResultHandle createValue(MethodContext context, MethodCreator method, ResultHandle array) {
// If the value is a proxy, it may be non-null at build time but become null
// when we actually create the value during initialization;
// so we need to use 'ofNullable' and not 'of' here.
return method.invokeStaticMethod(ofMethod(Optional.class, "ofNullable", Optional.class, Object.class),
context.loadDeferred(res));
}
};
} else {
return new DeferredArrayStoreParameter(param, expectedType) {
@Override
ResultHandle createValue(MethodContext context, MethodCreator method, ResultHandle array) {
return method.invokeStaticMethod(ofMethod(Optional.class, "empty", Optional.class));
}
};
}
} else if (param instanceof String) {
if (((String) param).length() > 65535) {
throw new RuntimeException("String too large to record: " + param);
}
return new DeferredParameter() {
@Override
ResultHandle doLoad(MethodContext context, MethodCreator method, ResultHandle array) {
return method.load((String) param);
}
};
} else if (param instanceof URL) {
String url = ((URL) param).toExternalForm();
return new DeferredParameter() {
@Override
ResultHandle doLoad(MethodContext context, MethodCreator method, ResultHandle array) {
AssignableResultHandle value = method.createVariable(URL.class);
try (TryBlock et = method.tryBlock()) {
et.assign(value, et.newInstance(MethodDescriptor.ofConstructor(URL.class, String.class), et.load(url)));
try (CatchBlockCreator malformed = et.addCatch(MalformedURLException.class)) {
malformed.throwException(RuntimeException.class, "Malformed URL", malformed.getCaughtException());
}View on GitHub (pinned to e1c734241f)
Solutions
- Do not pass the large string through the recorder; write it to a file at build time and pass the file path, loading contents at runtime
- Store the data as a classpath resource and read it from the runtime code instead of recording it
- Chunk the string into pieces under 65535 chars and reassemble in the recorder/runtime, though resource approach is preferred
- Compress the payload (e.g. base64 of gzip) only if it then fits under the limit
- If this comes from a config value, reduce the value size or move it out of recorded configuration
Example fix
// before: huge string via recorder
recorder.setSchema(hugeSchemaJson);
// after: write to file at build time, pass path
Path p = generatedResourcesDir.resolve("schema.json");
Files.writeString(p, hugeSchemaJson);
recorder.setSchemaLocation(p.toString()); Defensive patterns
Strategy: validation
Validate before calling
if (value != null && value.length() > 65535) {
throw new IllegalArgumentException(
"Value exceeds JVM constant-pool limit (65535); pass a resource path instead: " + value.length());
}
recorder.setValue(value); Type guard
static boolean isRecordableString(String s) {
return s == null || s.length() <= 65535;
} Try / catch
try {
recorder.setValue(largeString);
} catch (RuntimeException e) {
if (e.getMessage().startsWith("String too large")) {
Path f = outDir.resolve("payload.txt");
Files.writeString(f, largeString);
recorder.setValueFromFile(f.toString());
} else { throw e; }
} Prevention
- Check String lengths before passing to recorders
- Write large payloads to build-time resources and pass paths
- Keep embedded config/schema text under 64KB or externalize it
When it happens
Trigger: Passing a String argument longer than 65535 characters to a recorder method — e.g. embedded JSON, base64 blobs, generated SQL, PEM/keystore content, or a whole template body.
Common situations: Embedding a large certificate/keystore or serialized payload via a recorder; config values that ballooned; tests generating very large strings; setting schema/index definitions as a single recorded string.
Related errors
- Failed to record call to method ${call.method}
- All parameters have already been loaded, it is too late to c
- Unsupported wildcard type: ${wildcard}
- Cannot call getValue() at deployment time
- Failed to open path tree with root %s
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/c3a96bc488bcf660.
Report an issue: GitHub.