apache/hadoop · warning · RuntimeException
PrivilegedActionException with no underlying cause. UGI [" +
Error message
PrivilegedActionException with no underlying cause. UGI [" + this + "]: " + pae
What it means
UGI.doAs unwraps PrivilegedActionException and rethrows its cause with the original type. In the rare case the PAE carries no cause (getCause() null), it wraps the PAE itself in this RuntimeException rather than losing it. The real diagnostic value is the PrivilegedActionException in the message, not the wrapper.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java:1962
* @return the value from the run method
* @throws IOException if the action throws an IOException
* @throws Error if the action throws an Error
* @throws RuntimeException if the action throws a RuntimeException
* @throws InterruptedException if the action throws an InterruptedException
* @throws UndeclaredThrowableException if the action throws something else
*/
@InterfaceAudience.Public
@InterfaceStability.Evolving
public <T> T doAs(PrivilegedExceptionAction<T> action
) throws IOException, InterruptedException {
try {
tracePrivilegedAction(action);
return SubjectUtil.doAs(subject, action);
} catch (PrivilegedActionException pae) {
Throwable cause = pae.getCause();
LOG.debug("PrivilegedActionException as: {}", this, cause);
if (cause == null) {
throw new RuntimeException("PrivilegedActionException with no " +
"underlying cause. UGI [" + this + "]" +": " + pae, pae);
} else if (cause instanceof IOException) {
throw (IOException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
} else if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof InterruptedException) {
throw (InterruptedException) cause;
} else {
throw new UndeclaredThrowableException(cause);
}
}
}
private void tracePrivilegedAction(Object action) {
if (LOG.isTraceEnabled()) {
// would be nice if action included a descriptive toString()View on GitHub (pinned to 2add963021)
Solutions
- Read the full message: the PAE's toString identifies the action and where it originated
- Catch Throwable inside the PrivilegedExceptionAction and log it there, so the cause never depends on PAE wrapping
- If reproducible on one JDK only, compare JVM versions/vendor; file the mismatch rather than working around it blindly
Example fix
// before
ugi.doAs((PrivilegedExceptionAction<Void>) () -> { ...; return null; });
// after: capture diagnostics inside the action
ugi.doAs((PrivilegedExceptionAction<Void>) () -> {
try { ...; return null; }
catch (Throwable t) { LOG.error("action failed", t); throw t; }
}); Defensive patterns
Strategy: try-catch
Try / catch
try {
return ugi.doAs(action);
} catch (RuntimeException e) {
if (e.getMessage() != null
&& e.getMessage().contains("no underlying cause")) {
// inspect the PrivilegedActionException embedded in the message
LOG.error("doAs lost the underlying cause: {}", e.getMessage(), e);
}
throw e;
} Prevention
- Catch and log Throwable inside the PrivilegedExceptionAction itself
- Do not rely on PAE cause-chaining for diagnostics
- Pin JVM versions across the fleet so rare doAs behaviors are reproducible
When it happens
Trigger: Subject.doAs throwing a PrivilegedActionException constructed without a cause - unusual JVM/JDK behavior, custom doAs implementations, or exceptions reconstructed via deserialization inside the action.
Common situations: Almost never seen in practice; when it appears it usually accompanies exotic classloading or a custom SecurityManager/Subject doAs replacement. Most sightings are actually downstream symptoms logged by RPC layers calling doAs.
Related errors
- Illegal principal name " + name + ": " + ioe.toString()
- Failed to find user in name " + subject
- Problem with Kerberos auth_to_local name configuration
- Invalid attribute value for hadoop.kerberos.min.seconds.befo
- Subject does not contain a valid User
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/92e560134cda4c72.
Report an issue: GitHub.