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.

CodeConstantDescriptionResolution
0PK_SUCCESSSuccess.n/a
1PK_INVALID_INPUTNull pointer or invalid argument.Validate args; call pk_configure_memory before pk_init().
2PK_SCHEME_READ_ERRORFailed to read or deserialize the .pkp file.Verify the path and the deployed branch.
3PK_WITNESS_READ_ERRORFailed to read or parse the witness / input TOML.Run show-inputs to confirm the expected ABI.
4PK_PROOF_ERRORProof generation failed inside the prover.Reproduce with the CLI; if it also fails, inputs don’t satisfy the circuit.
5PK_SERIALIZATION_ERRORFailed to serialize the proof bytes or JSON.Check pk_get_memory_stats() for allocator pressure and re-run clean.
6PK_UTF8_ERRORA string argument wasn’t valid UTF-8.Pass valid UTF-8 null-terminated strings.
7PK_FILE_WRITE_ERRORFailed to write an output file.Check the output directory exists, is writable, and has free space.

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

FunctionPurposeReturns
pk_initInitialize the library. Call once before any other operation.PK_SUCCESS
pk_prove_to_fileGenerate a proof and write it to a file.PK_SUCCESS or PKError
pk_prove_to_jsonGenerate a proof as a JSON buffer (requires JSON support).PK_SUCCESS or PKError
pk_configure_memoryConfigure the mmap allocator. Must be called before pk_init.PK_SUCCESS or PK_INVALID_INPUT
pk_get_memory_statsRead RAM, swap, and peak memory statistics.PK_SUCCESS

pk_free_buf and pk_set_allocator return void. For exact signatures, see provekit_ffi.h.

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.