{"record":{"id":"76746654604b8e51","repo":"ethereum/go-ethereum","slug":"libsecp256k1-illegal-argument-s-n","errorCode":null,"errorMessage":"[libsecp256k1] illegal argument: %s\\n","messagePattern":"\\[libsecp256k1\\] illegal argument: (.+?)\\\\n","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crypto/secp256k1/libsecp256k1/src/util.h","lineNumber":99,"sourceCode":"            break; \\\n        default: ; \\\n    } \\\n    stmt; \\\n} while(0)\n\ntypedef struct {\n    void (*fn)(const char *text, void* data);\n    const void* data;\n} secp256k1_callback;\n\nstatic SECP256K1_INLINE void secp256k1_callback_call(const secp256k1_callback * const cb, const char * const text) {\n    cb->fn(text, (void*)cb->data);\n}\n\n#ifndef USE_EXTERNAL_DEFAULT_CALLBACKS\nstatic void secp256k1_default_illegal_callback_fn(const char* str, void* data) {\n    (void)data;\n    fprintf(stderr, \"[libsecp256k1] illegal argument: %s\\n\", str);\n    abort();\n}\nstatic void secp256k1_default_error_callback_fn(const char* str, void* data) {\n    (void)data;\n    fprintf(stderr, \"[libsecp256k1] internal consistency check failed: %s\\n\", str);\n    abort();\n}\n#else\nvoid secp256k1_default_illegal_callback_fn(const char* str, void* data);\nvoid secp256k1_default_error_callback_fn(const char* str, void* data);\n#endif\n\nstatic const secp256k1_callback default_illegal_callback = {\n    secp256k1_default_illegal_callback_fn,\n    NULL\n};\n\nstatic const secp256k1_callback default_error_callback = {","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/ethereum/go-ethereum/blob/6bb0588ad8e7f922e4ad5580f51265a4097af08f/crypto/secp256k1/libsecp256k1/src/util.h#L81-L117","documentation":"This is libsecp256k1's default illegal-argument callback: internal ARG_CHECK macros invoke it when an API is called with a NULL pointer, a non-canonical input, or an argument violating preconditions. The default implementation prints the message and calls abort(), killing the process — by design, because calling conventions were violated. Hosts can override it by defining USE_EXTERNAL_DEFAULT_CALLBACKS and installing their own callbacks.","triggerScenarios":"Passing NULL context/key/signature to any secp256k1 function; using a context created without the required SECP256K1_CONTEXT_* flags for that operation (e.g. signing with a VERIFY-only context in older API versions); passing overflow-length size_t arguments that trigger checked macros.","commonSituations":"Go bindings copying into undersized buffers; forgetting to check the return of secp256k1_ecdsa_pubkey_create before using the output; upgrading libsecp256k1 where previously-lenient NULL handling became ARG_CHECK'd; memory corruption from the surrounding application.","solutions":["Find the exact function and argument in the printed message string (it names them, e.g. 'ctx != NULL')","Check every pointer passed for NULL and every buffer size against the documented maximums before the call","Ensure contexts are created with the flags required by the operations performed on them","In embedded/production hosts, build with USE_EXTERNAL_DEFAULT_CALLBACKS and install a callback that maps to your error handling instead of abort"],"exampleFix":"// before\nsecp256k1_ecdsa_signature_parse_compact(NULL, &sig, in72); // ctx NULL -> abort\n\n// after\nif (ctx == NULL || in72 == NULL) return ERR_INVALID_ARG;\nif (!secp256k1_ecdsa_signature_parse_compact(ctx, &sig, in72)) return ERR_PARSE;","handlingStrategy":"validation","validationCode":"/* guard every call site's preconditions */\nif (ctx == NULL || pubkey == NULL || sig == NULL) {\n    return -1; /* caller error, no abort */\n}\nint ok = secp256k1_ecdsa_verify(ctx, sig, msg32, pubkey);\nif (!ok) { /* invalid signature, not a crash */ }","typeGuard":"static int sane_ctx(const secp256k1_context *ctx, unsigned need_flags) {\n    return ctx != NULL && (ctx->declassify_flags_dummy, 1); /* plus flag checks per API docs */\n}","tryCatchPattern":"/* Not catchable in C (abort). If hosting in another process, sandbox the crypto call:\n   run signing in a supervised child so an abort becomes a restartable failure. */\n#ifdef USE_EXTERNAL_DEFAULT_CALLBACKS\nvoid secp256k1_default_illegal_callback_fn(const char *str, void *d) {\n    host_report_illegal(str); /* log + longjmp/exception at the embedding layer */\n}\n#endif","preventionTips":["Check every pointer and return value before calling secp256k1 APIs","Create contexts with all flags your operations require","Build embedders with USE_EXTERNAL_DEFAULT_CALLBACKS to convert aborts into reportable errors"],"tags":["secp256k1","c","abort","argument-validation"],"backgroundTag":null,"analyzedSha":"6bb0588ad8e7f922e4ad5580f51265a4097af08f","analyzedAt":"2026-08-15T10:06:53.996Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}