Skip to content

FAQ & Troubleshooting

All error responses from DID.is conform to RFC 9457 Problem Details (application/problem+json).

Problem Code HTTP Status Root Cause Plain-Language Remedy
INVALID_DID 400 DID syntax fails W3C ABNF parsing. Check identifier format (did:<method>:<method-id>). Ensure method names contain only lowercase letters and digits.
INVALID_DID_URL 400 Malformed fragment, query, or path. In DID URLs, ensure # is percent-encoded as %23 when passed in HTTP paths. Path dereferencing (did:.../path) is unsupported.
NOT_FOUND 404 Upstream endpoint returned HTTP 404. For did:web, verify that /.well-known/did.json is published and publicly accessible over HTTPS.
EGRESS_BLOCKED 403 Host resolved to private/blocked IP. DID.is blocks loopback, private subnets, and cloud metadata (169.254.169.254). Target domain must resolve to public IP addresses.
UPSTREAM_UNAVAILABLE 502 Upstream host timed out or reset. Upstream server failed to respond within the 4-second egress timeout or dropped the TLS handshake. Check upstream server status.
PAYLOAD_TOO_LARGE 413 Request or upstream body exceeded cap. Ingress bodies are capped at 512 KiB; documents at 1 MiB; MCP at 2 MiB. Reduce file size or compress status lists.
RATE_LIMITED 429 Client IP exceeded token-bucket rate. Standard rate limit is 120 requests/min. Inspect the Retry-After header and throttle requests accordingly.
KEY_CAPACITY_EXHAUSTED 429 Project reached key limits. Projects permit 10 active and 100 retained keys. Revoke unused keys or contact enterprise support to increase retained capacity.
FEATURE_NOT_SUPPORTED 501 Requested operation is not implemented. Path dereferencing and custom resolution options are not implemented by policy.
METHOD_NOT_SUPPORTED 501 DID method is not supported. Native drivers exist for did:key, did:jwk, did:web, and did:webvh. Other methods (did:ion, did:indy, did:cheqd) are not implemented.
INVALID_DID_DOCUMENT 422 Document id does not match DID. The id property inside the published DID document must exactly match the requested DID string.

1. Why does my dossier show RESOLVED_WITH_WARNINGS?

Section titled “1. Why does my dossier show RESOLVED_WITH_WARNINGS?”

The DID document resolved, but contains non-fatal specification anomalies. Expand Structural Warnings in Level 4 to view specifics:

  • The document references an @context URI not present in the offline catalog.
  • The document declares verification methods that are not bound to any verification relationship (authentication, assertionMethod, etc.).
  • Deprecated legacy properties (e.g., publicKey instead of verificationMethod) were encountered.

2. Why does my Verifiable Credential status evaluate to INDETERMINATE?

Section titled “2. Why does my Verifiable Credential status evaluate to INDETERMINATE?”

DID.is fails closed. A credential evaluates to INDETERMINATE when:

  • The revocation Bitstring Status List was unreachable, timed out, or returned an HTTP error.
  • The status list’s own signature was invalid or signed by a different issuer.
  • The signing key was not explicitly listed in the issuer DID’s assertionMethod relationship.
  • The credential was signed using an unsupported cryptosuite (e.g., RDF-based eddsa-rdfc-2022).

3. Why does my MCP Server inspection show PROFILE_CHANGED under drift?

Section titled “3. Why does my MCP Server inspection show PROFILE_CHANGED under drift?”

PROFILE_CHANGED indicates that DID.is updated its internal canonicalization hash version from an unversioned profile to rfc8785-binary64-v1. This is an internal engine upgrade and does not signify that the remote tool provider altered their code.

4. Why does my did:web show control: NOT_ESTABLISHED?

Section titled “4. Why does my did:web show control: NOT_ESTABLISHED?”

By W3C definition, did:web updates are controlled by web hosting and DNS, not by cryptographic update keys. Whoever controls the web server can overwrite did.json at any time without holding a private key. If you require cryptographically enforceable update authority, migrate to did:webvh (verifiable history).


Q: Can I pay to have my identity marked as “Verified” or “Trusted”?
A: No. Verification on DID.is is strictly mathematical and cryptographic. Paid plans unlock higher API volumes, monitoring watches, and webhooks; they never alter verification outcomes.

Q: Does DID.is store copies of my private keys?
A: Never. DID.is is a resolution and verification engine. It only processes public keys. Submitting private keys via did:jwk is explicitly rejected with an error.

Q: How do I prove control of my DID on the public directory?
A: Navigate to /account and create a DID Claim. You can prove control via:

  1. Key Signature: Sign an ephemeral challenge using a key authorized under authentication.
  2. HTTPS File: Host the challenge token at /.well-known/did-is-claim.txt.
  3. DNS TXT Record: Publish the challenge as a _didis-claim DNS TXT record.
    Verified claims remain active for 90 days.

Q: Why doesn’t DID.is support RSA or BLS12-381 keys?
A: DID.is enforces modern, constant-time cryptographic suites with audited implementations. RSA is deprecated for decentralized identity due to key size and attack surface; BLS12-381 pairings require finalized W3C standardization before normative inclusion. Supported suites are Ed25519, NIST P-256, secp256k1, and X25519.

Q: Can I self-host DID.is in an air-gapped environment?
A: Yes. The core daemon (resolver-core) and CLI (didis) can be compiled from source (cargo build -p resolver-core) and executed locally without external internet access. In air-gapped environments, did:key and did:jwk resolve with 100% functionality; network methods (did:web) will report UPSTREAM_UNAVAILABLE.

Before deploying applications consuming DID.is in production environments, ensure your architecture satisfies these operational standards:

  • Handle HTTP 429 responses gracefully by reading the Retry-After header.
  • If self-hosting behind reverse proxies (Nginx, Cloudflare), set DIDIS_TRUST_PROXY=true to parse client IPs from sanitized X-Forwarded-For headers.

The core daemon enforces bounded internal concurrency to protect memory:

  • 32 concurrent standard operations
  • 4 concurrent expensive operations (credential verification, policy evaluation, MCP inspection)
  • 8 concurrent live SSE streams
  • If limits are reached, the server fails fast with HTTP 503 and Retry-After: 1. Ensure your client includes automatic jittered retry logic.

All outbound requests are subject to hardened network constraints:

  • Only HTTPS on port 443 is permitted.
  • Outbound requests to 127.0.0.1, RFC 1918 private subnets, and cloud metadata (169.254.169.254) are blocked at the DNS resolution stage.
  • Connections are strictly pinned to public IPs to eliminate DNS rebinding.
  • JSON-LD @context definitions are recognized offline via context_catalog.rs.
  • Do not design systems that rely on the resolver fetching custom remote JSON-LD schemas over HTTP. Unrecognized schemas resolve safely with known: false.