Errors and troubleshooting
Build handling around the stable code, not the human-readable message. Do not blindly retry 4xx responses; most require correcting identity, configuration, or signing logic.
| Code | HTTP | Cause | What to do |
|---|---|---|---|
SSO_REQUEST_INVALID | 400 | Form field missing/empty | Submit strings for clientId, payload, and signature. |
SSO_PAYLOAD_INVALID | 400 | Payload is not Base64URL JSON | Encode UTF-8 JSON once; inspect locally without logging production data. |
SSO_IDENTITY_REQUIRED | 400 | sub or email absent | Load both from trusted authenticated user state. |
SSO_NAME_REQUIRED | 400 | First-time JIT identity has no valid name | Sign the authenticated user's display/full name. |
SSO_CONFIGURATION_INVALID | 400 | Invalid origin/path administration | Use HTTPS origins and safe relative paths. |
SSO_INTEGRATION_UNAVAILABLE | 401 | Credential missing/revoked or tenant inactive | Confirm environment and tenant status; contact admin. |
SSO_CREDENTIAL_EXPIRED | 401 | Integration credential passed its configured expiry | Tenant administrator must renew or issue a credential. |
TENANT_CONTRACT_EXPIRED | 403 | Non-renewing tenant agreement ended | Contact the organization or Nanaade account owner. |
SSO_SIGNATURE_INVALID | 401 | Wrong secret/encoding or changed payload | Sign exact encoded payload with active secret. |
SSO_ASSERTION_EXPIRED | 401 | Expired, too long, or iat >60s ahead | Generate immediately, use seconds, synchronize clocks. |
SSO_ORIGIN_NOT_ALLOWED | 403 | Browser Origin not registered | Compare scheme, hostname, and port exactly. |
SSO_REDIRECT_NOT_ALLOWED | 403 | Destination origin invalid/unregistered | Sign a configured Nanaade workspace origin. |
SSO_MEMBERSHIP_REQUIRED | 403 | Roster-only tenant has no matching membership | Pre-provision and activate the membership. |
SSO_MEMBERSHIP_INACTIVE | 403 | Target membership is invited, suspended, or revoked | Correct its lifecycle state; do not create a duplicate. |
SSO_PORTAL_RETURN_NOT_ALLOWED | 403 | Portal return URL is absent, invalid, or not the submitting allowed origin | Sign an absolute URL on the registered portal origin. |
SSO_LAUNCH_CODE_REQUIRED | 400 | Assertion has no launch code | Send a documented code for the user-selected module action. |
SSO_LAUNCH_CODE_INVALID | 400 | Code is not in Nanaade's server registry | Correct the integration; never send a route or feature name as a substitute. |
SSO_LAUNCH_CONTEXT_INVALID | 400 | Deep-link context is missing or unsafe | Send only the required Nanaade record identifier. |
SSO_LAUNCH_FEATURE_NOT_LICENSED | 403 | Tenant requested a module/add-on it does not own | Remove the portal action or ask the tenant administrator about licensing. |
SSO_LAUNCH_AUDIENCE_DENIED | 403 | Nanaade-derived user audience cannot use the module | Use a launch intended for that user category. |
SSO_LAUNCH_PATH_NOT_ALLOWED | 403 | Server-resolved destination is outside the integration namespace | Ask Nanaade administration to review the registered destination paths. |
SSO_ASSERTION_REPLAYED | 409 | Nonce already consumed/missing | Generate a fresh random nonce for every launch. |
SSO_SUBJECT_MISMATCH | 409 | Membership bound to another subject | Correct the source identity; do not overwrite binding. |
SSO_TENANT_TRANSFER_REQUIRED | Browser redirect | User is active under another sponsored tenant | Let the user request transfer, contact support, or return to the portal. |
SSO_CONFLICT_TOKEN_INVALID | 400 | Conflict/return link expired or was altered | Start a fresh SSO launch. |
SSO_TRANSFER_CONTEXT_CHANGED | 409 | Membership changed after conflict detection | Start a fresh launch or contact support. |
SSO_REPLAY_STORE_UNAVAILABLE | 503 | Production nonce store unavailable | Wait for recovery; do not bypass replay protection. |
FEATURE_NOT_LICENSED | 403 | Module/add-on not granted | Tenant admin reviews licensing; do not loop SSO. |
RESUME_REQUIRED | 422 | The operation needs a parsed or Nanaade-built resume | Let Nanaade open its upload/builder flow; retry only after processing completes. |
JOB_ANALYSIS_REQUIRED | 422 | Applying or viewing a dependent result requires a completed job match | Open the resume match action for the selected job. |
ACADEMIC_PROFILE_REQUIRED | 422 | Career Pathway lacks field of study or current academic year | Ask the user to complete the Nanaade academic-profile step. |
CAREER_PROFILE_REQUIRED | 422 | Career roles and/or skill ratings have not been completed | Resume the Career Pathway setup flow. |
JOB_NOT_FOUND | 404 | The requested Nanaade job no longer exists or is unavailable | Return to Job Board and choose an active job. |
INTERVIEW_SKILLS_REQUIRED | 422 | Skills-based interview started without any selected skills | Ask the user to select at least one skill. |
TENANT_USAGE_LIMIT_REACHED | 429 | Organization reached a monthly provider-meter limit | Wait for reset or ask the tenant administrator to revise the limit. |
MEMBER_DAILY_LIMIT_REACHED | 429 | User reached their daily meter allowance | Wait until the next day or contact the tenant administrator. |
MEMBER_HOURLY_LIMIT_REACHED | 429 | User reached their hourly meter allowance | Wait until the next hour or contact the tenant administrator. |
TENANT_USAGE_CHECK_UNAVAILABLE | 503 | Nanaade could not safely verify a cost ceiling | Retry later; cost protection fails closed. |
Administrative credential operations may also report SSO_CREDENTIAL_EXISTS, SSO_CREDENTIAL_NOT_FOUND, or SSO_ENCRYPTION_NOT_CONFIGURED. These are Nanaade administrator/operations concerns, not errors your public portal should attempt to repair.
Data prerequisite response
Missing user data is not an authentication failure and not a licensing failure. Nanaade returns 422 Unprocessable Entity with a stable prerequisite code:
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json
{
"success": false,
"status": "failed",
"code": "RESUME_REQUIRED",
"prerequisite": "resume",
"feature": "job-board.resume-scoring",
"message": "Add or build your resume before using this feature.",
"action": {
"type": "navigate",
"href": "/dashboard/resume",
"label": "Add resume"
}
}
Nanaade's hosted module UI handles this response and presents the correct branded recovery flow. If your portal calls a documented API directly, branch on code, show a human-friendly explanation, and let the user return to the original portal path. Do not retry automatically while the prerequisite remains missing.
Diagnose a signature failure
Verify in this order:
- Client ID and secret come from the same environment/credential issue.
- The secret has no accidental whitespace or quotes.
- Payload is
base64url(UTF8(JSON.stringify(assertion))). - HMAC message is the encoded payload string.
- Digest output uses Base64URL, not hexadecimal or standard Base64.
- The payload is not modified after signing.
Diagnose an origin failure
In browser developer tools, inspect the request's Origin header. Compare only the exact scheme, host, and port to Nanaade configuration. A page URL path is irrelevant; a proxy that rewrites hosts may not be.
Diagnose a membership failure
Confirm the client ID belongs to the expected tenant, the target membership is active when one exists, normalized assertion email matches first binding, and the stable subject has not changed. For JIT tenants, also confirm that first launches include name. A successful login to your own portal proves identity only when your backend—not the browser—creates and signs the assertion.
Contacting support
Provide request ID, UTC timestamp, stable error code, client ID (or last characters), environment, expected destination, and whether the failure affects all users. Never provide the secret, full assertion, signature, session cookie, or user password.