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
- Run the XPipe daemon with sufficient privileges (or as the target user) so it can access that principal's secret store
- Encrypt for a principal the daemon can access, and use an alternative sharing mechanism for others
- Check OS-level credential-store/keychain permissions for the daemon user
- 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
- Run the daemon with enough privilege (or as the target user) for cross-user secret access
- Check OS keychain/credential-store permissions for the daemon user
- Prefer encrypting for principals known to be accessible; share secrets another way otherwise
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
- Unable to parse or decrypt secret
- Unknown principal " + pr
- Cannot delete category: " + cat.getName()
- Unsupported mode: " + msg.getMode().getDisplayName() + ". Su
- File path " + msg.getPath() + " is not absolute
AI-assisted analysis of xpipe-io/xpipe@d85ca821ba (2026-09-06).
Data as JSON: /api/errors/72c14e0cda3c6e75.
Report an issue: GitHub.