quarkusio/quarkus · error · RuntimeException

/tenant-restore-path-absolute-redirect must be restored

Error message

/tenant-restore-path-absolute-redirect must be restored

What it means

This RuntimeException is thrown intentionally by the /callback endpoint of the TenantRestorePathAbsoluteRedirect test resource. In Quarkus OIDC code-flow tests, the callback endpoint should never be reached after a successful login because the restore-path mechanism must redirect the user back to the original requested path (/tenant-restore-path-absolute-redirect) before the callback is invoked. Hitting the endpoint means the OIDC restore-path/absolute-redirect flow failed to restore the original URL.

Source

Thrown at integration-tests/oidc-code-flow/src/main/java/io/quarkus/it/keycloak/TenantRestorePathAbsoluteRedirect.java:26

import io.quarkus.security.Authenticated;

@Path("/tenant-restore-path-absolute-redirect")
public class TenantRestorePathAbsoluteRedirect {

    @Context
    UriInfo ui;

    @GET
    @Authenticated
    public String getTenant() {
        return ui.getAbsolutePath().toString();
    }

    @GET
    @Authenticated
    @Path("/callback")
    public String getTenantCallback() {
        throw new RuntimeException("/tenant-restore-path-absolute-redirect must be restored");
    }
}

View on GitHub (pinned to e1c734241f)

Solutions

  1. Verify the OIDC code-flow configuration restores the original path (restore-path-after-redirect enabled and correct callback path configured).
  2. Check that the initial request path /tenant-restore-path-absolute-redirect is protected by the correct tenant and that the state cookie carries the restore path.
  3. Inspect server logs for the OIDC redirect Location header; confirm it is absolute and points back to the original path.
  4. Re-run with quarkus.log.category.io.quarkus.oidc set to DEBUG to trace the redirect decisions.

Example fix

// before (flow broken, callback reached)
@GET @Authenticated @Path("/callback")
public String getTenantCallback() {
    throw new RuntimeException("/tenant-restore-path-absolute-redirect must be restored");
}
// after (correct flow: OIDC redirects back to the original path before the callback is ever hit;
// if the callback is legitimately reached, return the expected restored content instead)
@GET @Authenticated @Path("/callback")
public String getTenantCallback() {
    return "callback-reached"; // only valid when restore-path intentionally routes here
}
Defensive patterns

Strategy: validation

Validate before calling

if (requestPath.endsWith("/callback") && !oidcRestoredOriginalPath(request)) {
    throw new IllegalStateException("OIDC restore-path did not redirect back to the original path");
}

Type guard

boolean isRestoredPathRedirect(Response resp) {
    return resp.getStatusInfo().getFamily() == Response.Status.Family.REDIRECT
            && resp.getLocation() != null
            && resp.getLocation().isAbsolute();
}

Try / catch

try {
    String body = given().redirects().follow(false).get(path).asString();
} catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().contains("must be restored")) {
        // restore-path failed; inspect OIDC redirect configuration
    }
    throw e;
}

Prevention

When it happens

Trigger: GET /tenant-restore-path-absolute-redirect/callback is invoked, i.e. the OIDC authorization-code callback landed on the callback endpoint instead of redirecting back to the originally requested path with an absolute redirect.

Common situations: OIDC code-flow configuration changes (quarkus.oidc.restore-path-after-redirect / redirect-path handling), Keycloak/WireMock test-server changes altering redirect URLs, or regressions in Quarkus OIDC's restore-path behavior for absolute redirects.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/a6a9fc78110e4ddf. Report an issue: GitHub.