xpipe-io/xpipe · error · BeaconClientException

Principal " + p.getName() + " is not accessible

Error message

Principal " + p.getName() + " is not accessible

What it means

After resolving the requested principal, SecretEncryptExchange checks p.isAccessible(). The principal exists but the daemon's process cannot access it — commonly because encryption for that user requires elevated privileges or the daemon runs as a different user without permission. The request is rejected so secrets are never bound to an inaccessible principal.

Source

Thrown at app/src/main/java/io/xpipe/app/beacon/api/SecretEncryptExchange.java:56

                        .findFirst();
                if (byName.isPresent()) {
                    p = byName.get();
                } else {
                    var uuid = UuidHelper.parse(pr);
                    if (uuid.isPresent()) {
                        var principal = DataStorageAccessHandler.getInstance().getEncryptionPrincipal(uuid.get());
                        p = principal.orElse(null);
                    } else {
                        p = null;
                    }
                }

                if (p == null) {
                    throw new BeaconClientException("Unknown principal " + pr);
                }

                if (!p.isAccessible()) {
                    throw new BeaconClientException("Principal " + p.getName() + " is not accessible");
                }

                resolvedPrincipals.add(p);
            }
        }

        if (resolvedPrincipals.isEmpty()) {
            resolvedPrincipals.add(DataStorageAccessHandler.getInstance().getEncryptAllPrincipal());
        }

        var secret = MultiPrincipalSecret.of(InPlaceSecretValue.of(msg.getValue()), resolvedPrincipals);
        return Response.builder().encrypted(secret.serialize()).build();
    }

    @Jacksonized
    @Builder
    @Value
    public static class Request {

View on GitHub (pinned to d85ca821ba)

Solutions

  1. Run the XPipe daemon with sufficient privileges (or as the target user) so it can access that principal's secret store
  2. Encrypt for a principal the daemon can access, and use an alternative sharing mechanism for others
  3. Check OS-level credential-store/keychain permissions for the daemon user
  4. Consult XPipe docs on multi-user secret accessibility for your platform

Example fix

// before
request.setPrincipals(List.of("otheruser"));
// after
if (!daemonCanAccess("otheruser")) {
    logger.warn("Daemon cannot access 'otheruser'; encrypting for current user instead");
    request.setPrincipals(List.of(currentUserName));
} else {
    request.setPrincipals(List.of("otheruser"));
}
Defensive patterns

Strategy: fallback

Validate before calling

for (String pr : requested) {
    if (!daemonCanAccessPrincipal(pr)) {
        logger.warn("Principal not accessible to daemon: " + pr);
    }
}

Try / catch

try {
    return client.encryptSecret(request);
} catch (BeaconClientException e) {
    if (e.getMessage().endsWith("is not accessible")) {
        return client.encryptSecret(requestForCurrentUser());
    }
    throw e;
}

Prevention

When it happens

Trigger: Requesting encryption for a principal whose credentials/key material the daemon cannot read or impersonate: encrypting for another user while the daemon runs unprivileged, or on systems where cross-user secret access is restricted by OS policy.

Common situations: Daemon running as a service account while secrets target an interactive user; restricted OS keychains/credential stores; enterprise policies blocking cross-user access; missing admin elevation on Windows.

Understand the failure class

Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.

Related errors


AI-assisted analysis of xpipe-io/xpipe@d85ca821ba (2026-09-06). Data as JSON: /api/errors/72c14e0cda3c6e75. Report an issue: GitHub.