संक्षिप्त उत्तर: किसी पोर्ट पर कब्जा जमाए बैठी प्रक्रिया को बंद करने के लिए पहले उसका PID पहचानें, फिर उसे रोकें। macOS और Linux पर: lsof -ti :3000 | xargs kill (और kill -9 केवल तब, जब प्रक्रिया टिकी रहे)। Linux पर psmisc इंस्टॉल हो तो fuser -k 3000/tcp एक ही कमांड में दोनों काम कर देता है। Windows पर: netstat -ano | findstr :3000 और फिर taskkill /PID <pid> /F। Docker कंटेनर में kill नहीं, बल्कि docker stop चाहिए।
संदेश हमेशा एक जैसा होता है: next dev चलाते समय Error: listen EADDRINUSE: address already in use :::3000, या kubectl port-forward पर bind: address already in use। कोई प्रक्रिया अभी भी पोर्ट पकड़े बैठी है — अक्सर कोई डेवलपमेंट सर्वर जो जल्दी बंद किए गए टर्मिनल टैब में चल रहा था, कभी भूला हुआ कंटेनर, कभी कोई SSH टनल। यहाँ वे कमांड हैं जो हम रोज़ाना इस्तेमाल करते हैं, सिस्टमों के बीच के अंतर, और वे तीन स्थितियाँ जहाँ प्रक्रिया को बंद करना गलत फैसला है।

पोर्ट पर कब्जा जमाए बैठी प्रक्रिया को कैसे बंद करें?
दो चरणों में: पोर्ट पर सुन रही प्रक्रिया का PID खोजें, फिर उस PID को रोकने का सिग्नल भेजें। कमांड सिस्टम पर निर्भर करती है।
| सिस्टम | पहचानें | बंद करें | |
|---|---|---|---|
| macOS | lsof -i :3000 | kill $(lsof -ti :3000) | |
| Linux (आधुनिक) | ss -ltnp 'sport = :3000' | kill <pid> | |
Linux (psmisc) | fuser 3000/tcp | fuser -k 3000/tcp | |
| Windows (cmd) | `netstat -ano \ | findstr :3000` | taskkill /PID <pid> /F |
| Windows (PowerShell) | Get-NetTCPConnection -LocalPort 3000 | Stop-Process -Id <pid> | |
| Docker | docker ps --filter publish=3000 | docker stop <नाम> |
जो बारीकी मायने रखती है: lsof -t केवल PID देता है, जिससे वह सीधे kill के साथ जोड़ा जा सकता है। macOS पर lsof -ti :3000 सबसे छोटा रूप है जो आपकी अपनी प्रक्रियाओं के लिए sudo के बिना काम करता है। lsof का दस्तावेज़ीकरण Apple टूल्स के मैनुअल पेज में है और यह macOS पर डिफ़ॉल्ट रूप से मौजूद होता है; Linux पर यह अब हमेशा इंस्टॉल नहीं होता, इसीलिए iproute2 द्वारा दिए जाने वाले ss को जानना उपयोगी है।
कुछ भी इंस्टॉल किए बिना Linux वाला तरीका
net-tools के परित्याग के बाद से ss अधिकांश डिस्ट्रिब्यूशनों के बेस पैकेज का हिस्सा है:
# Qui écoute sur 3000 ? (-l listen, -t tcp, -n numérique, -p process)
sudo ss -ltnp 'sport = :3000'
# LISTEN 0 511 *:3000 *:* users:(("next-server",pid=48213,fd=23))
kill 48213
sudo के बिना, जो प्रक्रियाएँ आपकी नहीं हैं उनके लिए users: कॉलम खाली रहता है: आपको पोर्ट व्यस्त दिखता है, पर दोषी नहीं। «पोर्ट तो व्यस्त है, मगर मेरी कमांड कुछ नहीं ढूँढ़ पा रही» की यह सबसे बड़ी वजह है।
याद रखने लायक alias
हम डेव मशीनों की dotfiles में यह फंक्शन हमेशा डालते हैं, क्योंकि इससे PID कॉपी-पेस्ट करने की ज़रूरत नहीं पड़ती:
# ~/.zshrc ou ~/.bashrc
killport() {
local pid
pid=$(lsof -ti ":$1" -sTCP:LISTEN)
if [ -z "$pid" ]; then
echo "Aucun processus en écoute sur le port $1"
return 1
fi
echo "Arrêt du PID $pid sur le port $1"
kill "$pid" || kill -9 "$pid"
}
-sTCP:LISTEN अहम है: इसके बिना lsof -ti :3000 किसी दूसरी मशीन के पोर्ट 3000 की तरफ जाने वाले आउटगोइंग कनेक्शन भी दिखा देता है। तब आप सर्वर की जगह अपना ब्राउज़र या HTTP क्लाइंट बंद कर बैठेंगे।
सीधे kill -9 क्यों न करें?
क्योंकि kill -9 SIGKILL भेजता है, जिसे प्रक्रिया पकड़ नहीं सकती: न कनेक्शन बंद होते हैं, न बफ़र खाली होते हैं, न अस्थायी फ़ाइलों की सफाई होती है। Next.js के डेवलपमेंट सर्वर पर यह बेअसर है। बाकी तीन मामलों में नहीं।
- डेटाबेस जो 5432 या 3306 पर सुन रहा हो: SIGKILL से रीस्टार्ट पर रिकवरी करनी पड़ती है। PostgreSQL इसे संभाल लेता है (यह बिजली जाने के बराबर है), लेकिन सही तरीके से बंद करना अब भी
pg_ctl stopयाsystemctl stop postgresqlही है। सर्वर शटडाउन पर PostgreSQL का दस्तावेज़smart,fastऔरimmediateमोड समझाता है; SIGKILLimmediateसे भी खराब है। - संतान प्रक्रियाओं वाली प्रक्रिया: पैरेंट पर
killकरने से चाइल्ड प्रक्रियाएँ अनाथ रह सकती हैं और पोर्ट पकड़े रहती हैं (npm run devके साथ यह आम बात है, जो एक सब-प्रोसेस चलाता है)। पूरे ग्रुप को बंद करें:kill -- -$(ps -o pgid= <pid> | tr -d ' ')। - कंटेनर: होस्ट से दिखने वाला PID कंटेनर के अंदर की प्रक्रिया का होता है। उसे मारने पर Docker असंगत स्थिति में छूट जाता है;
docker stopपहले SIGTERM भेजता है और ग्रेस पीरियड (डिफ़ॉल्ट 10 सेकंड) के बाद SIGKILL।
इसलिए सही क्रम हमेशा यही है: SIGTERM (kill), दो सेकंड इंतज़ार, और SIGKILL (kill -9) केवल तब जब पोर्ट अभी भी व्यस्त हो।
पोर्ट खाली है, फिर भी bind नाकाम हो रहा है
तीन कारण, सभी आम, और इनमें से कोई भी kill से हल नहीं होता।
1. TIME_WAIT स्थिति। सॉकेट बंद होने के बाद कर्नेल उस quadruplet को लगभग 60 सेकंड तक TIME_WAIT में रखता है (Linux पर 2×MSL)। जो सर्वर SO_REUSEADDR विकल्प सेट नहीं करता, वह इस अवधि में दोबारा शुरू होने से इनकार करेगा। ss -tan state time-wait '( sport = :3000 )' से जाँचें। सही जवाब केवल इंतज़ार करना है, या सर्वर को ठीक करना — net.ipv4.tcp_tw_reuse से छेड़छाड़ नहीं।
2. Windows द्वारा आरक्षित पोर्ट। Hyper-V, WSL2 और Windows NAT Service बूट पर डायनेमिक पोर्ट रेंज आरक्षित कर लेते हैं, और पोर्ट 3000 या 5000 उसी रेंज में आ सकता है। तब netstat कोई भी प्रक्रिया नहीं दिखाता। बहिष्करण सूची देखें:
netsh interface ipv4 show excludedportrange protocol=tcp
अगर आपका पोर्ट किसी बहिष्कृत रेंज में है, तो पोर्ट बदलें या netsh int ipv4 add excludedportrange से उसे स्पष्ट रूप से आरक्षित करें। Windows रीस्टार्ट के बाद «कल तो चल रहा था» का यह विशिष्ट लक्षण है।
3. 1024 से छोटे पोर्ट पर अनुमतियाँ। Linux पर 80 या 443 पर bind करने के लिए CAP_NET_BIND_SERVICE या root चाहिए। त्रुटि EACCES होती है, EADDRINUSE नहीं — प्रक्रिया ढूँढ़ने से पहले एरर कोड पढ़ें।

और Docker, Kubernetes या CI में?
kill वाली आदत यहाँ काम नहीं करती: इन परिवेशों में पोर्ट किसी ऑर्केस्ट्रेटर द्वारा प्रबंधित ऑब्जेक्ट के पास होता है, और उसी ऑर्केस्ट्रेटर से बात करनी होती है।
- पोर्ट पब्लिश करने वाला Docker कंटेनर।
docker ps --filter publish=3000कंटेनर बता देता है;docker stop <नाम>उसे ठीक से रोक देता है। अगरdocker psकुछ नहीं दिखाता, तो वे कंटेनर देखें जो रुके हुए हैं पर जिनका पोर्ट प्रॉक्सी द्वारा अभी भी मैप है:docker ps -aचलाएँ, और अंतिम उपाय के तौर पर डेमॉन रीस्टार्ट करें। - भूतिया
kubectl port-forward। बैकग्राउंड में चलाया गयाport-forwardटर्मिनल बंद होने के बाद भी जीवित रहता है।lsof -ti :8080 -sTCP:LISTENएकkubectlप्रक्रिया दिखाता है: उसी को बंद करना है, किसी pod को नहीं। Kubernetes दस्तावेज़ीकरण की सेवाओं तक पहुँच की सर्वोत्तम प्रथाएँ याद दिलाती हैं किport-forwardएक डीबग टूल है, एक्सपोज़र का तरीका नहीं। - किसी pod में पोर्ट पहले से व्यस्त। एक ही pod के दो कंटेनर नेटवर्क namespace साझा करते हैं: एक ही pod में दो
containerPort: 3000होने पर दूसरे कोEADDRINUSEमिलेगा। निदान कंटेनर के लॉग में होता है, होस्ट पर नहीं। - GitLab CI runner। साझा runner पर कोई पिछला job किसी सेवा को सुनता हुआ छोड़ सकता है। आँख बंद करके मारने के बजाय अपने jobs को डायनेमिक पोर्ट पर सुनने दें (
PORT=0, जहाँ सर्वर इसे समर्थन करता है) या GitLab CI services इस्तेमाल करें, जिन्हें अपना नेटवर्क मिलता है। यही तर्क हमने Kubernetes पर Next.js के लिए GitLab CI/CD पाइपलाइन में भी रखा था: जो job runner की स्थिति पर निर्भर है, वह पुनरुत्पादनीय नहीं है।
समस्या भुगतने की जगह उससे कैसे बचें?
पोर्ट को रचना से ही गैर-टकराव वाला बनाकर। चार आदतें, जो 90% मामलों को खत्म कर देती हैं:
- हर प्रोजेक्ट के लिए एक पोर्ट, जो रिपॉज़िटरी के
.envमें लिखा हो, डेवलपरों के दिमाग में नहीं: ऐप A के लिए 3001, ऐप B के लिए 3002। Next.jsnext dev -p 3001याPORT=3001स्वीकार करता है। - Ctrl+C से बंद करें, टैब बंद करके कभी नहीं। टर्मिनल एम्युलेटर और शेल के अनुसार, विंडो बंद करने पर प्रोसेस ग्रुप को SIGHUP हमेशा नहीं जाता; अनाथ सर्वरों की यह सबसे आम वजह है।
compose upपरCtrl+Cकी जगहdocker compose down: पहला विकल्प नेटवर्क और पोर्ट मैपिंग भी हटा देता है।- टीम प्रोजेक्ट्स के लिए एक
predevस्क्रिप्ट जो शुरू करने से पहले पोर्ट खाली कर दे:
{
"scripts": {
"predev": "lsof -ti :3000 -sTCP:LISTEN | xargs -r kill || true",
"dev": "next dev"
}
}
xargs (GNU) का -r पोर्ट खाली होने पर kill को बिना आर्गुमेंट चलाने से रोकता है; macOS पर -r के बिना xargs और साथ में || true इस्तेमाल करें।

प्रोडक्शन में व्यस्त पोर्ट का विशेष मामला
प्रोडक्शन में व्यस्त पोर्ट डेव मशीन की झुंझलाहट नहीं है: यह अटका हुआ डिप्लॉयमेंट है। आम परिदृश्य एक rolling update है, जहाँ पुराने pod ने अपना पोर्ट छोड़ा नहीं और नया शुरू हो गया। Kubernetes पर, hostPort या hostNetwork: true के साथ टकराव तय है: पोर्ट नोड पर कब्जा होता है, pod में नहीं। इसका जवाब किसी प्रक्रिया को मारना नहीं, बल्कि hostPort हटाकर एक Service के साथ ingress या Gateway का रास्ता अपनाना है — वही व्यवस्था जो हमने ingress-nginx की जगह Gateway API पर लिखे लेख में बताई है।
एकल-सर्वर VM पर यही टकराव systemd से चलाए गए दो वर्शनों के बीच दिखता है। सही क्रम ExecStop और फिर ExecStart है, जिसमें TimeoutStopSec आपके HTTP सर्वर के कनेक्शन बंद होने के समय से अधिक हो (Node.js keep-alive कनेक्शन server.close() और चल रही रिक्वेस्ट पूरी होने से पहले बंद नहीं करता)।
अक्सर पूछे जाने वाले प्रश्न
सबसे छोटी «kill port» कमांड कौन सी है?
macOS और Linux पर, जहाँ lsof इंस्टॉल है: kill $(lsof -ti :3000 -sTCP:LISTEN)। psmisc वाले Linux पर: fuser -k 3000/tcp। Windows पर: netstat -ano | findstr :3000 में PID पढ़ने के बाद taskkill /PID <pid> /F। इन सिस्टमों पर कोई नेटिव killport कमांड नहीं है; यह हमेशा दो टूल्स का मेल होता है।
पोर्ट व्यस्त होने पर भी lsof -i :3000 कुछ क्यों नहीं दिखाता?
तीन कारण, आवृत्ति के क्रम में: आप root नहीं हैं और प्रक्रिया किसी दूसरे उपयोगकर्ता की है (sudo के साथ दोबारा चलाएँ); पोर्ट किसी कंटेनर के पास है जिसकी मैपिंग Docker प्रॉक्सी से होकर जाती है (docker ps से खोजें); पोर्ट Windows/WSL2 द्वारा आरक्षित रेंज में है (netsh interface ipv4 show excludedportrange)।
पोर्ट मुक्त करने के लिए रीस्टार्ट ज़रूरी है?
नहीं, असामान्य मामलों को छोड़कर। पोर्ट या तो किसी प्रक्रिया से अटकता है (जिसे बंद किया जा सकता है), या TIME_WAIT स्थिति से (जो लगभग एक मिनट में खुद खत्म हो जाती है), या किसी सिस्टम आरक्षण से (Windows पर netsh से बिना रीस्टार्ट बदला जा सकता है)। मशीन रीस्टार्ट करना कारण को छिपा देता है और अगली बार वह फिर लौट आता है।
प्रक्रिया को बंद करने से पहले यह कैसे जानें कि वह क्या कर रही है?
ps -p <pid> -o pid,ppid,user,etime,command पूरी कमांड लाइन, उपयोगकर्ता और चलने का समय बताता है। डेव मशीन पर कई दिनों का etime लगभग हमेशा किसी अनाथ सर्वर का संकेत है; तीस सेकंड पहले शुरू हुई प्रक्रिया शायद साझा सेशन पर पेयर प्रोग्रामिंग करता आपका सहकर्मी हो।
सारांश
- मारने से पहले पहचानें:
lsof -ti :<port> -sTCP:LISTEN(macOS/Linux),ss -ltnp(Linux),netstat -ano | findstr(Windows)। - पहले SIGTERM (
kill), SIGKILL (kill -9) केवल दूसरे उपाय के रूप में — और डेटाबेस पर कभी पहले नहीं। -sTCP:LISTENफ़िल्टर सर्वर की जगह आउटगोइंग कनेक्शन मारने से बचाता है।- Docker, Kubernetes या CI में
killइस्तेमाल नहीं होता:docker stop,port-forwardहटाना, या job में डायनेमिक पोर्ट। - पोर्ट खाली पर bind अस्वीकृत:
TIME_WAIT, Windows/WSL2 की आरक्षित रेंज, या 1024 से छोटे पोर्ट की अनुमतियाँ याद रखें। - रोकथाम:
.envमें हर प्रोजेक्ट का एक पोर्ट, Ctrl+C से बंद करना,docker compose down,predevस्क्रिप्ट।
अगर ये पोर्ट टकराव आपके स्टेजिंग परिवेशों या डिप्लॉयमेंट्स में भी होते हैं, तो यह आम तौर पर हाथ से बनाए गए नेटवर्क एक्सपोज़र का संकेत है। हम इस तरह की आर्किटेक्चर को अपने इंफ्रास्ट्रक्चर और संचालन मिशनों में फिर से गढ़ते हैं, और डेवलपमेंट परिवेशों को एप्लिकेशन डेवलपमेंट की तरफ से औद्योगिक स्तर पर व्यवस्थित करते हैं। किसी ठोस मामले पर बात करने के लिए संपर्क पेज सबसे छोटा रास्ता है।


