Skip to content

FFI error codes

The ProveKit C FFI (tooling/provekit-ffi/) returns a PKError code on every function call. PK_SUCCESS (0) means success; any other value indicates failure. Hosts (Swift, Kotlin, Python, custom C/C++) should branch on the numeric code in production paths.

The codes below are mirrored from provekit_ffi.h.

CodeConstantMeaningCommon causesResolution
0PK_SUCCESSSuccess.,,
1PK_INVALID_INPUTInvalid input parameters, for example a null pointer where one was required.Forgot to populate a path string, passed a null buffer, or pre-init memory configuration left ram_limit_bytes at 0.Validate non-null pointers and required path arguments before the call. Configure memory before pk_init().
2PK_SCHEME_READ_ERRORFailed to read or deserialize the .pkp (prover key) file.Missing file, wrong path, corrupted artifact, or a .pkp from an incompatible ProveKit version.Verify the path through the host filesystem APIs. Confirm the file came from the matching prepare run on the deployed branch.
3PK_WITNESS_READ_ERRORFailed to read or parse the witness / input TOML for this circuit.Wrong file, mismatched circuit ABI, malformed TOML, or incorrect hex encoding in a witness map.Run provekit-cli show-inputs on the corresponding proof to confirm the expected ABI. Validate witness encoding (hex strings ≤ 32 bytes, BN254 field range).
4PK_PROOF_ERRORProof generation failed inside the prover.Inputs that don’t satisfy the circuit (constraint violation), exhausted memory, or a bug in a witness builder for unusual inputs.Reproduce with the CLI using the same inputs. If the CLI fails too, the inputs likely don’t satisfy the circuit. Otherwise capture stderr and open an issue.
5PK_SERIALIZATION_ERRORFailed to serialize the output (proof bytes or JSON).Internal serializer failure, often paired with an unexpected allocator or buffer-size condition.Free intermediate buffers, check pk_get_memory_stats() for allocator pressure, and re-run from a clean state.
6PK_UTF8_ERRORUTF-8 conversion error.A path or string argument contained bytes that don’t form valid UTF-8.Ensure all const char * arguments are valid UTF-8 null-terminated strings.
7PK_FILE_WRITE_ERRORFailed to write an output file.Path doesn’t exist, parent directory is read-only, or disk is full.Create the output directory first. Check permissions. Verify free space on the target volume.

Every FFI entry point that performs work returns a PKError (as int):

FunctionPurposeReturns
pk_init()Initialize the library. Call once before any other operation.PK_SUCCESS on success.
pk_prove_to_file(prover_path, input_path, out_path)Generate a proof and write it to a file.PK_SUCCESS or a PKError code.
pk_prove_to_json(prover_path, input_path, *out_buf)Generate a proof as a JSON buffer (when built with JSON support).PK_SUCCESS or a PKError code.
pk_configure_memory(ram_limit_bytes, use_file_backed, swap_file_path)Configure the mmap allocator. Must be called before pk_init().PK_SUCCESS or PK_INVALID_INPUT.
pk_get_memory_stats(*ram_used, *swap_used, *peak_ram)Read RAM, swap, and peak memory statistics.PK_SUCCESS.

pk_free_buf and pk_set_allocator return void.

let status = pk_prove_to_file(proverPath, inputPath, outputPath)
switch status {
case Int32(PK_SUCCESS.rawValue):
return .success
case Int32(PK_SCHEME_READ_ERROR.rawValue),
Int32(PK_WITNESS_READ_ERROR.rawValue):
// Bad input, re-fetch artifacts, validate paths, retry once.
return .reloadArtifacts
case Int32(PK_PROOF_ERROR.rawValue),
Int32(PK_SERIALIZATION_ERROR.rawValue):
return .failedProof
default:
return .systemError
}

Server: distinguish soft and hard failures

Section titled “Server: distinguish soft and hard failures”

PK_INVALID_INPUT, PK_WITNESS_READ_ERROR, PK_UTF8_ERROR are client-shaped, the request was malformed. Return a 4xx HTTP status.

PK_PROOF_ERROR, PK_SERIALIZATION_ERROR, PK_FILE_WRITE_ERROR, and PK_SCHEME_READ_ERROR are environment-shaped, your runtime is unhealthy (missing files, allocator pressure, or a real prover bug). Return a 5xx and alert.

When an FFI host reports an error, the fastest reproduction is the CLI:

Terminal window
cargo run --release --bin provekit-cli -- prove --prover circuit.pkp --input Prover.toml
cargo run --release --bin provekit-cli -- verify --verifier circuit.pkv --proof proof.np
cargo run --release --bin provekit-cli -- show-inputs --hex circuit.pkv proof.np

If the CLI fails the same way, the artifact set is the problem. If the CLI succeeds, the FFI host integration is.