xpipe-io/xpipe · error · BeaconClientException

Unknown principal " + pr

Error message

Unknown principal " + pr

What it means

SecretEncryptExchange resolves each requested principal (user/system account) by name or id. When a principal string from msg cannot be resolved to a known principal on this system, the daemon throws 'Unknown principal <pr>'. Encryption must be bound to real principals so the resulting secret can later be decrypted for them.

Source

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

            for (String pr : msg.getPrincipals()) {
                var byName = DataStorageAccessHandler.getInstance().getAllEncryptionPrincipals().stream()
                        .filter(encryptionPrincipal ->
                                encryptionPrincipal.getName().equals(pr))
                        .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();
    }

View on GitHub (pinned to d85ca821ba)

Solutions

  1. List the available principals on the target host and use an exact matching name/id
  2. Fix typos or update the username after account renames
  3. Verify you are calling the daemon on the machine where the principal exists
  4. Pass the identifier in the format the API expects (UUID vs name)

Example fix

// before
request.setPrincipals(List.of("svc-app"));
// after
List<String> known = client.listPrincipals();
if (!known.contains("svc-app")) {
    throw new IllegalArgumentException("svc-app not on this host; known: " + known);
}
request.setPrincipals(List.of("svc-app"));
Defensive patterns

Strategy: validation

Validate before calling

List<String> known = client.listPrincipals();
for (String pr : requested) {
    if (!known.contains(pr)) {
        throw new IllegalArgumentException("Unknown principal: " + pr + "; known: " + known);
    }
}

Try / catch

try {
    client.encryptSecret(request);
} catch (BeaconClientException e) {
    if (e.getMessage().startsWith("Unknown principal")) {
        logger.warn("Principal missing on host, dropping it: " + e.getMessage());
        request.setPrincipals(request.getPrincipals().stream()
            .filter(p -> !e.getMessage().endsWith(p)).toList());
    } else throw e;
}

Prevention

When it happens

Trigger: Calling the encrypt endpoint with a principal entry (username/UUID) that doesn't exist on the daemon's host — renamed user, deleted account, wrong identifier format, or requesting encryption for a user on the wrong target machine.

Common situations: Hardcoded usernames that differ between dev and prod hosts; users renamed or removed after secrets were first provisioned; passing a display name where a UUID (or vice versa) is required; scripts running against a different host than intended.

Understand the failure class

Background: "User not found", "Invalid user", and "does not exist": what missing-user lookup errors mean across Rocket.Chat, LiteLLM, Phabricator, rustfs, and pnpm — this error's family across 10 libraries.

Related errors


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