Skip to content

POST /api/v1/contracts/call returns HTTP 500 for gas estimation when sender is ECDSA-keyed and value > 0 #13742

Description

@quiet-node

Description

On a POST /api/v1/contracts/call request with "estimate": true, the web3 module returns
HTTP 500 (Internal Server Error) when both of the following are true:

  • from is an ECDSA (secp256k1) account, and
  • value is greater than 0.

The same request returns HTTP 200 when value is omitted, or when from is an ED25519 account.

Expected: the request returns an HTTP 200 gas estimate (as it does for the ED25519 sender and the
no-value cases).

Observed on mirror node v0.156.0 (web3 module), deployed via solo against consensus node
v0.73.0.

Steps to reproduce

  1. Deploy a local network with solo (consensus node v0.73.0, mirror node v0.156.0):

    cat > /tmp/mirror-node-values.yaml <<'EOF'
    web3:
      env:
        HIERO_MIRROR_WEB3_OPCODE_TRACER_ENABLED: "true"
        HIERO_MIRROR_WEB3_EVM_NETWORK: "OTHER"
    EOF
    
    cat > /tmp/falcon-local.yml <<EOF
    network:
      --release-tag: "v0.73.0"
      --node-aliases: "node1"
    setup:
      --release-tag: "v0.73.0"
      --node-aliases: "node1"
    consensusNode:
      --node-aliases: "node1"
    mirrorNode:
      --enable-ingress: true
      --pinger: true
      --mirror-node-version: "v0.156.0"
      --values-file: "/tmp/mirror-node-values.yaml"
    EOF
    
    npx @hashgraph/solo@0.78.0 one-shot falcon deploy \
      --values-file /tmp/falcon-local.yml \
      --dev --deploy-explorer=false --deploy-relay=false

    The deploy output prints funded accounts. Note one 0.0.100x account address (these are
    ECDSA / hex private key), e.g. 0.0.1003.

  2. Port-forward the web3 module:

    kubectl port-forward -n one-shot svc/mirror-1-web3 8545:80
  3. Send the gas-estimation call with an ECDSA from and value > 0 (replace EC with the
    account from step 1):

    EC=0x05fba803be258049a27b820088bab1cad2058871
    URL=http://127.0.0.1:8545/api/v1/contracts/call
    
    curl -s -w '\nHTTP %{http_code}\n' -X POST "$URL" -H 'Content-Type: application/json' \
      -d "{\"from\":\"$EC\",\"to\":\"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\",\"value\":5000000000,\"estimate\":true}"

    Result: HTTP 500, body {"_status":{"messages":[{"message":"Internal Server Error","detail":"","data":""}]}}.

  4. For comparison, the same call without value returns HTTP 200:

    curl -s -w '\nHTTP %{http_code}\n' -X POST "$URL" -H 'Content-Type: application/json' \
      -d "{\"from\":\"$EC\",\"to\":\"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\",\"estimate\":true}"
  5. And the same call with an ED25519 from (treasury 0.0.2) and value > 0 returns HTTP 200:

    curl -s -w '\nHTTP %{http_code}\n' -X POST "$URL" -H 'Content-Type: application/json' \
      -d '{"from":"0x0000000000000000000000000000000000000002","to":"0x742d35Cc6634C0532925a3b844Bc454e4438f44e","value":5000000000,"estimate":true}'

Observed results

from key type value HTTP status
ECDSA none / 0 200
ECDSA > 0 500
ED25519 (treasury 0.2) > 0 200

Additional context

When the 500 occurs, the mirror-1-web3 pod logs the following:

kubectl logs -n one-shot deploy/mirror-1-web3
2026-06-16T20:36:17.556Z ERROR tomcat-handler-185 o.h.m.w.c.GenericControllerAdvice Generic error:  jakarta.servlet.ServletException: Handler dispatch failed: java.lang.Error: Structure.getFieldOrder() on class org.hyperledger.besu.nativelib.secp256k1.LibSecp256k1$secp256k1_pubkey returns names ([data]) which do not match declared field names ([])
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:978)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:866)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1000)
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:903)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:653)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:874)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:723)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:128)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:107)
	at org.hiero.mirror.web3.config.MetricsFilter.doFilterInternal(MetricsFilter.java:53)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:107)
	at org.hiero.mirror.web3.config.LoggingFilter.doFilterInternal(LoggingFilter.java:48)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:107)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:107)
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:107)
	at org.springframework.web.filter.ServerHttpObservationFilter.doFilterInternal(ServerHttpObservationFilter.java:110)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:107)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:199)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:107)
	at org.springframework.web.filter.ForwardedHeaderFilter.doFilterInternal(ForwardedHeaderFilter.java:174)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:107)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:165)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:77)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:492)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:113)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:83)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:72)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:397)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:1272)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1801)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
	at java.base@25.0.2/java.lang.Thread.runWith(Thread.java:1487)
	at java.base@25.0.2/java.lang.VirtualThread.run(VirtualThread.java:456)
	at java.base@25.0.2/java.lang.VirtualThread$VThreadContinuation$1.run(VirtualThread.java:248)
Caused by: java.lang.Error: Structure.getFieldOrder() on class org.hyperledger.besu.nativelib.secp256k1.LibSecp256k1$secp256k1_pubkey returns names ([data]) which do not match declared field names ([])
	at com.sun.jna.Structure.getFields(Structure.java:1158)
	at com.sun.jna.Structure.deriveLayout(Structure.java:1337)
	at com.sun.jna.Structure.calculateSize(Structure.java:1234)
	at com.sun.jna.Structure.calculateSize(Structure.java:1180)
	at com.sun.jna.Structure.allocateMemory(Structure.java:430)
	at com.sun.jna.Structure.<init>(Structure.java:220)
	at com.sun.jna.Structure.<init>(Structure.java:208)
	at com.sun.jna.Structure.<init>(Structure.java:195)
	at com.sun.jna.Structure.<init>(Structure.java:187)
	at org.hyperledger.besu.nativelib.secp256k1.LibSecp256k1$secp256k1_pubkey.<init>(LibSecp256k1.java:106)
	at com.hedera.node.app.hapi.utils.EthSigsUtils.recoverAddressFromPubKey(EthSigsUtils.java:47)
	at com.hedera.node.app.hapi.utils.EthSigsUtils.recoverAddressFromPubKey(EthSigsUtils.java:63)
	at com.hedera.node.app.service.token.AliasUtils.recoverAddressFromPubKey(AliasUtils.java:124)
	at com.hedera.node.app.service.token.AliasUtils.extractEvmAddress(AliasUtils.java:75)
	at com.hedera.node.app.service.token.impl.handlers.CryptoCreateHandler.preHandle(CryptoCreateHandler.java:200)
	at com.hedera.node.app.workflows.dispatcher.TransactionDispatcher.dispatchPreHandle(TransactionDispatcher.java:103)
	at com.hedera.node.app.workflows.handle.dispatch.ChildDispatchFactory.preHandleChild(ChildDispatchFactory.java:378)
	at com.hedera.node.app.workflows.handle.dispatch.ChildDispatchFactory.createChildDispatch(ChildDispatchFactory.java:186)
	at com.hedera.node.app.workflows.handle.DispatchHandleContext.dispatch(DispatchHandleContext.java:495)
	at com.hedera.node.app.service.contract.impl.exec.scope.HandleHederaNativeOperations.createHollowAccount(HandleHederaNativeOperations.java:139)
	at com.hedera.node.app.service.contract.impl.state.DispatchingEvmFrameState.tryLazyCreation(DispatchingEvmFrameState.java:502)
	at com.hedera.node.app.service.contract.impl.state.ProxyWorldUpdater.tryLazyCreation(ProxyWorldUpdater.java:236)
	at com.hedera.node.app.service.contract.impl.exec.processors.CustomMessageCallProcessor.doTransferValueOrHalt(CustomMessageCallProcessor.java:309)
	at com.hedera.node.app.service.contract.impl.exec.processors.CustomMessageCallProcessor.start(CustomMessageCallProcessor.java:152)
	at org.hyperledger.besu.evm.processor.AbstractMessageProcessor.process(AbstractMessageProcessor.java:191)
	at com.hedera.node.app.service.contract.impl.exec.FrameRunner.runToCompletion(FrameRunner.java:143)
	at com.hedera.node.app.service.contract.impl.exec.FrameRunner.runToCompletion(FrameRunner.java:91)
	at com.hedera.node.app.service.contract.impl.exec.TransactionProcessor.processTransactionWithParties(TransactionProcessor.java:151)
	at com.hedera.node.app.service.contract.impl.exec.TransactionProcessor.processTransaction(TransactionProcessor.java:122)
	at com.hedera.node.app.service.contract.impl.exec.ContextTransactionProcessor.call(ContextTransactionProcessor.java:185)
	at com.hedera.node.app.service.contract.impl.handlers.ContractCallHandler.handle(ContractCallHandler.java:62)
	at com.hedera.node.app.workflows.dispatcher.TransactionDispatcher.dispatchHandle(TransactionDispatcher.java:221)
	at com.hedera.node.app.workflows.handle.DispatchProcessor.tryHandle(DispatchProcessor.java:167)
	at com.hedera.node.app.workflows.handle.DispatchProcessor.processDispatch(DispatchProcessor.java:139)
	at com.hedera.node.app.workflows.handle.DispatchProcessor.processDispatch(DispatchProcessor.java:118)
	at com.hedera.node.app.workflows.standalone.TransactionExecutors.lambda$newExecutor$1(TransactionExecutors.java:227)
	at com.hedera.node.app.workflows.standalone.TransactionExecutors$DefaultTracerBinding.runWhere(TransactionExecutors.java:338)
	at com.hedera.node.app.workflows.standalone.TransactionExecutors.lambda$newExecutor$0(TransactionExecutors.java:226)
	at org.hiero.mirror.web3.service.TransactionExecutionService.execute(TransactionExecutionService.java:92)
	at org.hiero.mirror.web3.service.ContractCallService.doProcessCall(ContractCallService.java:115)
	at org.hiero.mirror.web3.service.ContractCallService.callContract(ContractCallService.java:106)
	at org.hiero.mirror.web3.service.ContractExecutionService.estimateGas(ContractExecutionService.java:96)
	at org.hiero.mirror.web3.service.ContractExecutionService.lambda$processCallWithGas$0(ContractExecutionService.java:66)
	at org.hiero.mirror.web3.common.ContractCallContext.lambda$run$0(ContractCallContext.java:80)
	at java.base@25.0.2/jdk.internal.vm.ScopedValueContainer.callWithoutScope(ScopedValueContainer.java:162)
	at java.base@25.0.2/jdk.internal.vm.ScopedValueContainer.call(ScopedValueContainer.java:147)
	at java.base@25.0.2/java.lang.ScopedValue$Carrier.runWith(ScopedValue.java:62)
	at java.base@25.0.2/java.lang.ScopedValue$Carrier.call(ScopedValue.java:419)
	at org.hiero.mirror.web3.common.ContractCallContext.run(ContractCallContext.java:80)
	at org.hiero.mirror.web3.service.ContractExecutionService.processCallWithGas(ContractExecutionService.java:56)
	at org.hiero.mirror.web3.service.ContractExecutionService.processCall(ContractExecutionService.java:49)
	at org.hiero.mirror.web3.controller.ContractController.call(ContractController.java:44)
	at java.base@25.0.2/java.lang.reflect.Method.invoke(Method.java:565)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:252)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:184)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:934)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:853)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:86)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
	... 45 common frames omitted

2026-06-16T20:36:17.560Z  WARN tomcat-handler-185 o.h.m.w.c.LoggingFilter [::1] POST /api/v1/contracts/call in 9 ms : 500 Handler dispatch failed: java.lang.Error: Structure.getFieldOrder() on class org.hyperledger.besu.nativelib.secp256k1.LibSecp256k1$secp256k1_pubkey returns names ([data]) which do not match declared field names ([]) - {"nonce":"0x1","value":5000000000,"from":"0x7d55e4b98d6478b8c8379e1bd6d8b767a19b0616","to":"0xe4ac0763398050e5d2b868672f0fe624888580ba","estimate":true} 

The same HTTP 500 and the same log line were observed in two environments:

  • GitHub Actions CI runner (Linux, x86_64).
  • Local solo deployment (macOS, arm64).

Hedera network

other (local solo network)

Version

mirror node v0.156.0 (web3 module); consensus node v0.73.0; solo v0.78.0

Operating system

Linux (CI runner) and macOS (local)

Metadata

Metadata

Assignees

Labels

bugType: Something isn't workingweb3Area: Web3 API

Type

No type

Fields

No fields configured for issues without a type.

Projects

Status
✅ Done

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions