ethereum/go-ethereum · error

Trying to insert into existing key

Error message

Trying to insert into existing key

What it means

Error "Trying to insert into existing key" thrown in ethereum/go-ethereum.

Solutions

  1. StackTrie does not support overwriting an existing key. Ensure keys are inserted exactly once and in strictly increasing (sorted) order.
  2. If updates are needed, collect all key/value pairs first and build the StackTrie once from the final set.

Example fix

sort.Slice(kvs, func(i, j int) bool { return bytes.Compare(kvs[i].K, kvs[j].K) < 0 })
for _, kv := range kvs {
    st.Update(kv.K, kv.V) // each key exactly once, ascending order
}

When it happens

Trigger: Calling StackTrie.Update/insert with a key that already exists in the trie, or with unsorted input keys.

Common situations: Building a stacktrie from duplicate or unsorted key/value lists (e.g., receipts/tx lists containing duplicates).


AI-assisted analysis of ethereum/go-ethereum@6bb0588ad8 (2026-08-15). Data as JSON: /api/errors/b509d490a121362f. Report an issue: GitHub.

Appendix: source

Thrown at trie/stacktrie.go:288

		// Insert both child leaves where they belong:
		origIdx := st.key[diffidx]
		newIdx := key[diffidx]
		p.children[origIdx] = n
		p.children[newIdx] = o
		st.key = st.key[:diffidx]

	case leafNode: /* Leaf */
		// Compare both key chunks and see where they differ
		diffidx := st.getDiffIndex(key)

		// Overwriting a key isn't supported, which means that
		// the current leaf is expected to be split into 1) an
		// optional extension for the common prefix of these 2
		// keys, 2) a fullnode selecting the path on which the
		// keys differ, and 3) one leaf for the differentiated
		// component of each key.
		if diffidx >= len(st.key) {
			panic("Trying to insert into existing key")
		}

		// Check if the split occurs at the first nibble of the
		// chunk. In that case, no prefix extnode is necessary.
		// Otherwise, create that
		var p *stNode
		if diffidx == 0 {
			// Convert current leaf into a branch
			st.typ = branchNode
			st.children[0] = nil
			p = st
		} else {
			// Convert current node into an ext,
			// and insert a child branch node.
			st.typ = extNode
			st.children[0] = stPool.Get().(*stNode)
			st.children[0].typ = branchNode
			p = st.children[0]

View on GitHub (pinned to 6bb0588ad8)