{"record":{"id":"161772b6e2abd069","repo":"tailscale/tailscale","slug":"got-data-packet-from-unexpected-source-v","errorCode":null,"errorMessage":"got data packet from unexpected source, %v","messagePattern":"got data packet from unexpected source, (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"prober/derp.go","lineNumber":500,"sourceCode":"\t\t}\n\t})\n\n\t// Receive the packets.\n\trecvFinishedC := make(chan error, 1)\n\twg.Go(func() {\n\t\tdefer close(recvFinishedC) // to break out of 'select' below.\n\t\tfromDERPPubKey := fromc.SelfPublicKey()\n\t\tfor {\n\t\t\tm, err := toc.Recv()\n\t\t\tif err != nil {\n\t\t\t\trecvFinishedC <- err\n\t\t\t\treturn\n\t\t\t}\n\t\t\tswitch v := m.(type) {\n\t\t\tcase derp.ReceivedPacket:\n\t\t\t\tnow := time.Now()\n\t\t\t\tif v.Source != fromDERPPubKey {\n\t\t\t\t\trecvFinishedC <- fmt.Errorf(\"got data packet from unexpected source, %v\", v.Source)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tseq := binary.BigEndian.Uint64(v.Data)\n\t\t\t\ttxRecordsMu.Lock()\n\t\t\tfindTxRecord:\n\t\t\t\tfor i, record := range txRecords {\n\t\t\t\t\tswitch {\n\t\t\t\t\tcase record.seq == seq:\n\t\t\t\t\t\trtt := now.Sub(record.at)\n\t\t\t\t\t\tqdh.add(rtt.Seconds())\n\t\t\t\t\t\ttxRecords = slices.Delete(txRecords, i, i+1)\n\t\t\t\t\t\tbreak findTxRecord\n\t\t\t\t\tcase record.seq > seq:\n\t\t\t\t\t\t// No sent time found, probably a late arrival already\n\t\t\t\t\t\t// recorded as drop by sender when deleted.\n\t\t\t\t\t\tbreak findTxRecord\n\t\t\t\t\tcase record.seq < seq:\n\t\t\t\t\t\tcontinue","sourceCodeStart":482,"sourceCodeEnd":518,"githubUrl":"https://github.com/tailscale/tailscale/blob/5201273aec737d6372ab7423c31c04ca3ca2a0c2/prober/derp.go#L482-L518","documentation":"The receiving DERP client got a derp.ReceivedPacket whose v.Source key differs from the sending client's public key. A derper only forwards packets addressed to this client's key, so traffic from any other source key means some other sender targeted the receiver's key - typically key reuse across prober instances or stale packets still in flight after a reconnect.","triggerScenarios":"Running two prober instances that reuse the same client key pair; a late packet from a previous connection arriving after the client reconnected with a new key; a derper misforwarding traffic between clients.","commonSituations":"Duplicated prober deployments sharing generated keys or state directories; old and new prober running concurrently during a rollout; rarely, a derper forwarding bug.","solutions":["Confirm only one prober instance is using this receiver key pair","Regenerate the prober client keys so no other sender can address them","Capture the offending v.Source key printed in the error and search derper logs for its connection","Re-run once - a single occurrence right after restart is likely a stale in-flight packet"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"switch v := m.(type) {\ncase derp.ReceivedPacket:\n\tif v.Source != wantKey {\n\t\t// Option A (prober semantics): fail loudly, as the code does.\n\t\t// Option A is recommended: an unexpected source on a fresh per-run key\n\t\t// almost certainly means key reuse or misforwarding - investigate.\n\t\treturn fmt.Errorf(\"got data packet from unexpected source, %v\", v.Source)\n\t}\n}","preventionTips":["Generate a fresh client key pair per prober run so no other sender can address your receiver","Never share prober state directories or keys between concurrent deployments","Log the offending source key - it identifies exactly which client is cross-talking"],"tags":["derp","prober","pubkey","security","go"],"backgroundTag":"unexpected-packet-source","analyzedSha":"5201273aec737d6372ab7423c31c04ca3ca2a0c2","analyzedAt":"2026-08-18T08:17:25.280Z","contentChangedAt":"2026-08-18T08:17:25.280Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}