gRPC & HTTPS

Troubleshooting

Start with the method from chapter 11: status code → layer, details → cause, the other side's log when the client's view is thin.

Setup and environment

SymptomCauseFix
openssl was not found on PATHOpenSSL missingWindows: Git for Windows includes it (C:\Program Files\Git\usr\bin); add to PATH, or docker compose --profile tools run --rm --no-deps toolbox python certs/scripts/certs.py generate. macOS: brew install openssl. Linux: install the openssl package.
error: certificates missing (...) from tasks.py upcerts/out/ emptyuv run python certs/scripts/certs.py generate
Bind for 127.0.0.1:8080 failed: port is already allocatedanother process uses the portstop it, or copy .env.example to .env and set e.g. REST_HTTP_HOST_PORT=18080 (then use that port in commands)
grpc-server stays unhealthy on Linuxcontainers cannot read the 0600 keysstart with python scripts/tasks.py up, which sets LOCAL_UID/LOCAL_GID; or export them yourself: LOCAL_UID=$(id -u) LOCAL_GID=$(id -g) docker compose up -d --wait
invalid mount config ... bind source path does not exista certificate file is missinggenerate certificates; the mounts deliberately refuse to create empty paths
ModuleNotFoundError: No module named 'grpc_client'not run through uv, or not from the repo rootrun uv sync, then uv run python -m ... from the repository root
RuntimeError: The grpc package installed is at version ...generated code newer than grpciouv sync (versions are pinned together)
Greeting prints ????? on Windowslegacy console code pageuse Windows Terminal; the clients already write UTF-8

gRPC call failures

StatusDetails containMeaningNext step
UNAVAILABLEerrors resolvingDNS: name unknown herefrom your machine use localhost; Compose names work only inside Compose
UNAVAILABLEConnection refusednothing listeningdocker compose ps; check the port
UNAVAILABLECERTIFICATE_VERIFY_FAILED: unable to get local issuer certificatewrong trust anchoruse --ca certs/out/ca.crt; certs.py inspect server
UNAVAILABLEHostname Verification Check failedname not in SANconnect via localhost; certs.py inspect server
UNAVAILABLEcertificate has expiredserver cert out of datecerts.py rotate server + restart (the grpc-expired service is meant to fail)
UNAVAILABLEEnd of TCP stream or Connection abortedserver rejected the handshakedocker compose logs grpc-server --since 5m; PEER_DID_NOT_RETURN_A_CERTIFICATE = no client cert, CERTIFICATE_VERIFY_FAILED = untrusted client cert
UNAVAILABLEWRONG_VERSION_NUMBERTLS client, plaintext servercheck port / --plaintext
UNIMPLEMENTEDMethod not found!contract mismatchcompare client and server .proto versions
UNAUTHENTICATEDrequires a client certificateAdminService without mTLSuse port 50052 with --cert/--key
PERMISSION_DENIEDnot authorizedidentity lacks permissionuse admin.crt, or change GRPC_ADMIN_IDENTITIES deliberately
DEADLINE_EXCEEDEDDeadline Exceededdeadline shorter than the workmeasure; set --deadline with headroom
INVALID_ARGUMENTthe rule that failedbad request contentfix the request; do not retry
RESOURCE_EXHAUSTEDlarger than maxmessage over the size limitsmaller payloads or GRPC_MAX_MESSAGE_BYTES

You will also see gRPC core log lines like I1016 12:52:15 ... ssl_transport_security.cc:2530] Handshake failed with error .... They come from the gRPC library itself and carry the same TLS reason. Set GRPC_VERBOSITY=ERROR to hide them.

REST / HTTPS failures

SymptomCauseFix
IP address mismatch, certificate is not valid for '127.0.0.1'name not in SANuse https://localhost:8443
unable to get local issuer certificatewrong CA--ca certs/out/ca.crt
Windows curl: schannel: ... revocation status is unknown / CERT_TRUST_REVOCATION_STATUS_UNKNOWNWindows' TLS library wants revocation info that a local CA does not publishadd --ssl-revoke-best-effort (keeps chain and hostname checks) or use examples/rest_client.py
PowerShell: curl behaves oddlycurl is an alias for Invoke-WebRequest in Windows PowerShell 5.1type curl.exe
422 with extra_forbiddenunknown JSON fieldsend only name, language, simulated_delay_ms
413body over REST_MAX_BODY_BYTESsmaller body

Challenge

SymptomFix
No working copy yetuv run python -m challenge start
FAIL ... must trust exactly the workshop CA although the call worksthe checker also validates the profile; set ca = "certs/out/ca.crt"
Scenario passes locally but not in Dockerrun Docker commands with the challenge service, which shares grpc-server's network so localhost matches
Want to start overuv run python -m challenge reset NN or start --force

Website

SymptomFix
Diagrams show as code blocksJavaScript disabled, or Mermaid failed to load; the diagram source and the surrounding text remain readable
Progress lostprogress lives in your browser's local storage; private windows and clearing site data reset it
npm ci fails on Node 18/20use Node 22 (frontend/package.json engines)

Source: docs/troubleshooting.md