xpipe-io/xpipe · error · IllegalArgumentException

Principal ${name} is not accessible

Error message

Principal ${name} is not accessible

What it means

MultiPrincipalSecret.of() encrypts an internal secret for each provided EncryptionPrincipal. Before encrypting, every principal must report isAccessible() == true (i.e. its key material can be loaded). If any principal is inaccessible, the factory refuses and throws this IllegalArgumentException rather than producing a partially-encrypted secret.

Source

Thrown at app/src/main/java/io/xpipe/app/secret/MultiPrincipalSecret.java:167

                    if (iteration > maxAccessibleIteration) {
                        maxAccessibleIteration = iteration;
                        maxAccessibleSecret = secret.inPlace();
                    }
                }
            }
        }

        if (entries.isEmpty()) {
            return null;
        }

        return new MultiPrincipalSecret(entries, maxAccessibleSecret);
    }

    public static MultiPrincipalSecret of(SecretValue internalSecret, Set<EncryptionPrincipal> principals) {
        for (EncryptionPrincipal principal : principals) {
            if (!principal.isAccessible()) {
                throw new IllegalArgumentException("Principal " + principal.getName() + " is not accessible");
            }
        }

        var l = new ArrayList<Entry>();
        for (EncryptionPrincipal principal : principals) {
            var enc = AesSecretValue.encrypt(internalSecret.getSecret(), principal.getSecretKey());
            l.add(new Entry(principal, enc.getEncryptedValue(), 1, EncryptionToken.of(principal)));
        }
        return new MultiPrincipalSecret(l, internalSecret.inPlace());
    }

    public MultiPrincipalSecret with(InPlaceSecretValue secret, DataStoreAccessScope scope) {
        if (!supportsScopeEncryption(scope)) {
            throw new IllegalArgumentException("Scope " + scope + " is not supported");
        }

        var secretUnchanged = secret == null || Arrays.equals(secret.getSecret(), this.secret.getSecret());
        if (secretUnchanged && getScope().equals(scope) && isScopeValid()) {

View on GitHub (pinned to d85ca821ba)

Solutions

  1. Filter the principal set to only principals where isAccessible() is true before calling of()
  2. Re-create or re-link the inaccessible principal (restore its key/credentials)
  3. Remove stale principals from the configured set

Example fix

// before
var s = MultiPrincipalSecret.of(secret, allPrincipals);
// after
var usable = allPrincipals.stream().filter(EncryptionPrincipal::isAccessible).collect(toSet());
var s = MultiPrincipalSecret.of(secret, usable);
Defensive patterns

Strategy: validation

Validate before calling

var usable = principals.stream().filter(EncryptionPrincipal::isAccessible).collect(java.util.stream.Collectors.toSet());
if (usable.size() != principals.size()) { /* drop or repair inaccessible principals */ }

Type guard

java.util.function.Predicate<EncryptionPrincipal> accessible = EncryptionPrincipal::isAccessible;

Try / catch

try { MultiPrincipalSecret.of(secret, principals); } catch (IllegalArgumentException e) { if (e.getMessage().contains("is not accessible")) { /* filter principals and retry */ } else throw e; }

Prevention

When it happens

Trigger: Calling MultiPrincipalSecret.of(secret, principals) where at least one principal in the set returns false from isAccessible() — e.g. its underlying key/credential is missing, rotated, or from a now-unavailable storage backend.

Common situations: Restoring a secrets file on a machine whose keyring/account no longer matches; principals referencing removed user accounts or stale hardware keys; passing a mix of valid and legacy principals.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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