ChargeLink Native

Troubleshooting: Symptom to Action

Troubleshoot in layers. Do not jump to protocol decoding when the installed binary, license, NIC, port or gRPC service has not been proven. Every JSON failure carries a stable error code (CL-USAGE-001, CL-CONFIG-001, CL-LICENSE-001, CL-PROFILE-001, CL-RUNTIME-001, CL-ARTIFACT-001, CL-CONTRACT-001, CL-UNSUPPORTED-001, CL-IO-001, CL-SERIALIZATION-001, CL-INTERNAL-001) and an operator_action; read them first (exit codes).

The layers of an ISO 15118 session and where each one is diagnosed Order in which a session is established, and in which failures must be isolated 1 · SDP UDP 15118, multicastto ff02::1 on thelink-local interface Fails on: wrong NIC,IPv6 off, zone index,firewall Evidence:sdp_diagnostics.json 2 · TCP Advertised addressand port: 50118 or49152–65535 Fails on: wrongadvertise-ipv6, portrule, peer routing Evidence:evse_listener_status 3 · TLS ISO 15118-20:TLS 1.3 mutualISO 15118-2: optionalDIN 70121: none Fails on: version,chain, clock, missingclient certificate Evidence:tls_handshake_diagnostics.json 4 · V2GTP Frame header andpayload type0x8001 … 0x8004 Fails on: invalidlength or payloadtype, truncation Evidence: traces\live-v2gtp-frames 5 · EXI SupportedApp-Protocol, then theselected schema Fails on: decodeerror, unmatchedrequest encoding Evidence: decodeverdict per frame 6 · Session Setup, authorize,schedule, precharge,charge loop, stop Fails on: sequence,response budget,plant safety state Evidence: session_handshake_gate evse live-closure-gate --require-sdp --require-tcp-peer --require-tls --require-v2gtp --require-exi reports which layers were observed for a run.
Isolate failures layer by layer; each layer has its own evidence file.

Fast triage order

  1. Identity — version, license, profile.
  2. Environment — doctor, roots, permissions, NIC.
  3. Runtime — stale sessions, role locks, port ownership, gRPC health.
  4. Transport — IPv6 zone, SDP, TCP, TLS.
  5. Protocol — V2GTP, EXI, message sequence, response budgets.
  6. Integration — VeriStand mapping, automation client.
  7. Evidence — run ID, trace, first error timestamp.

Failure matrix

SymptomUsually meansCheck firstCorrective action
chargelink not foundPATH or installation pathTest-Path $CLUse the full path; reopen the shell after changing PATH.
Exit 2, CL-USAGE-001Wrong subcommand or flag for the installed versionchargelink <cmd> --helpCompare with the CLI reference; scripts from other releases must be checked.
Exit 70, CL-UNSUPPORTED-001The command is accepted by the parser but has no implementation in the installed version—Use the commands documented in this manual (for example test instead of scenario/suite/campaign).
Exit 20, CL-LICENSE-001No active or supplied license, or a package entitlement is missinglicense status, license entitlementsActivate the supplied file; confirm the purchased package entitlement.
Exit 10, CL-CONFIG-001Invalid configuration (for example --backend ethernet, empty PFX password variable, non-positive live-case value)the message fieldCorrect the option; the message names the accepted values.
Exit 40, CL-RUNTIME-001, "role lock"Another EVSE/EVCC session is live or stale in this runtime rootruntime list, runtime locksevse stop / evcc stop, or runtime recover --stale-only.
Different roots see different sessionsMissing --runtime-root/--artifact-root; defaults are relative to the working directorythe runtime_root field in any resultPass the same two root options on every command.
EVSE cannot bind / address in useAnother process owns UDP 15118 or the TCP portnetstat -ano | findstr ':15118 :50118'Stop the owner or use --tcp-port 0.
EVCC never discovers the EVSEWrong NIC, IPv6 disabled, zone index, firewallGet-NetAdapter, IPv6 binding, --interface-index, rules for UDP 15118 from fe80::/10Correct the adapter and advertised address; recreate the firewall rules.
"unreachable network" (10051) on the EVCCPeer address carries the peer's zone index instead of this machine's--peer-ipv6 suffixUse fe80::<peer>%<LOCAL_INDEX>.
SDP succeeds, TCP failsAdvertised address or port not reachablesdp_diagnostics.json, evse_listener_status.jsonAdvertise the bench adapter's link-local address; open the TCP port from fe80::/10.
TCP succeeds, TLS failsVersion, chain, clock or missing client certificatetls_handshake_diagnostics.json, evse tls-pki-doctor, w32tm /query /statusSee TLS, PKI and Plug & Charge. ISO 15118-20 needs TLS 1.3 mutual; do not use the SChannel or dev adapters.
TLS succeeds, then no protocol progressRequest encoding not matched by the reference responder, or response budget exceededtraces\live-v2gtp-frames.jsonl, session_handshake_artifact_gate.jsonIdentify the first unmatched or rejected frame; escalate with the trace. For ISO 15118-20 dynamic behaviour use the plant-coupled lane.
gRPC health failsServer not running, wrong endpoint, port conflictTest-NetConnection 127.0.0.1 -Port 50051Start integration serve; check the state root.
gRPC healthy, automation failsClient request or API version mismatchintegration session-smoke, capabilities.api_versionProve the built-in smokes, then debug the client against the proto of the same version.
GetProtocolState is unobservedBy design: the session carries no "listener" object, or the listener was started from the CLIbound-live-protocol-observer capabilityBind the session or read the listener artifacts; this is not a fault.
Every gRPC or REST call fails with CL-RUNTIME-001 "does not have valid authentication credentials"The client has no token or an old one (the server writes a new api-token at every start)the message names the file it triedSet CHARGELINK_API_TOKEN_FILE to the running server's <state-root>\api-token, or start the server with the runtime root's default state root.
integration serve exits 40 at start--listen names a non-loopback addressthe diagnostic envelopeUse 127.0.0.1 or [::1]; remote access is not offered.
VeriStand bench: owner host stops before the listener startsNI version, another deployed project or VeriStand client, leftover processes<run>\host.log, the failure file in host-output, NI file hashesUndeploy and close the other VeriStand client; end leftover chargelink.exe and ChargeLink.Veristand.XilHost processes; see NI VeriStand Bench, Troubleshooting.
VeriStand bench: plant values do not moveChanged system definition or contract files, safe start-up state held, safety input activemanifest\SHA256SUMS, Send-OwnerCommand.ps1 -Command GetStatusRestore the package files from the verified ZIP; see VeriStand Signal Mapping.
Rate stabilisation timeoutEngine rate too high for the PCengine rate, power plan, CPU loadUse the 500 Hz SIL configuration; repeat the timing check.
Scripted DC-CAN "hardware" run has hardware_loop_evidence_complete: falseExpected: the scripted lanes start no CAN driver; hardware mode records an operator attestation—None; see Scripted DC-CAN Lanes.
Test case shows inconclusive or blockedNo evidence bound, or prerequisite absentcampaign_status.jsonAttach an evidence manifest (test run --evidence live); satisfy or document the blocker. Never relabel as FAIL.
No artifactsWrong artifact root or permissionglobal --artifact-root, directory ACLUse an explicit writable root; preserve any failure evidence before retrying.
Integrity check failsFiles changed after the runartifacts integrity outputQuarantine and repeat the run; do not regenerate the manifest.

Layer checks

Identity and environment

chargelink --version
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json license status
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json doctor --strict
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json profile show <PROFILE_ID>

Runtime

chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json runtime list
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json runtime locks
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json runtime inspect --run-id <RUN_ID>
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json runtime recover --stale-only --dry-run
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json runtime recover --stale-only

Transport

Get-NetAdapter | Format-Table ifIndex,Name,Status -AutoSize
Get-NetIPAddress -AddressFamily IPv6 | Where-Object IPAddress -like 'fe80::*' | Format-Table InterfaceIndex,InterfaceAlias,IPAddress -AutoSize
ping -6 'fe80::<PEER>%<LOCAL_INDEX>'
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evse live-preflight --source external-evcc --protocol <P> --profile-id <ID> --host '::' --tcp-port 50118 --udp-port 15118 --advertise-ipv6 $Advertise --interface-index $IfIndex

Protocol

Get-Content "$Data\artifacts\<RUN_ID>\traces\live-v2gtp-frames.jsonl" | Select-Object -First 40
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evse live-closure-gate --run-id <RUN_ID> --source external-evcc --require-sdp --require-tcp-peer --require-v2gtp --require-exi

Useful separation: SDP → TCP → TLS → V2GTP → EXI/application → charging sequence. A later-layer failure does not invalidate earlier transport success; say which layer failed when escalating.

Prepare a support bundle

Preserve the failing run directory, then follow Support Escalation. Do not rerun over the same run ID.