Ask HN: मुझे वास्तव में UUID v4 collision का सामना करना पड़ा...
(news.ycombinator.com)- डेटाबेस ने आज डुप्लिकेट UUID v4 का पता लगाया, और मौजूदा मान 2025 में जोड़े गए रिकॉर्ड के
b6133fd6-70fe-4fe3-bed6-8ca8fc9386cdसे बिल्कुल मेल खाता था - इस्तेमाल किया जा रहा पैकेज npm का uuid है, और बताया गया है कि
import { v4 as uuidv4 } from "uuid";के बादconst document_id = uuidv4();से जनरेट करके उसे डेटाबेस में डाला जाता है - डेटाबेस में लगभग 15,000 रिकॉर्ड ही हैं, इसलिए यह सांख्यिकीय रूप से असंभव लगता है, और पूछा जा रहा है कि क्या किसी और ने भी ऐसा अनुभव किया है
1 टिप्पणियां
Hacker News की राय
jandrewrogers: यह हैरानी की बात है, लेकिन काफ़ी आम है। UUIDv4 की सुरक्षा इस धारणा पर टिकी है कि एक high-quality entropy source मौजूद है, लेकिन hardware defect, सामान्य software bug, और entropy के बारे में developers की समझ की कमी से यह धारणा आसानी से टूट जाती है
entropy source के खराब होने का पता लगाना काफ़ी महंगा होता है, इसलिए लगभग कोई यह करता नहीं, और आम तौर पर टकराव होने के बाद ही पता चलता है। इसी वजह से कई high-reliability, high-assurance systems में UUIDv4 को स्पष्ट रूप से प्रतिबंधित किया जाता है
entropy source जितने ज़्यादा हों उतना अच्छा, और उनमें से अच्छी संख्या non-deterministic होनी चाहिए। छोटे-से game में भी अगर mouse coordinates, button input के बीच का interval, start button दबाने से पहले के frames जैसी values को initial seed में मिला दिया जाए, तो भले ही अंदर pseudo-random generator इस्तेमाल हो, prediction काफ़ी मुश्किल हो जाती है। अगर CloudFlare 100 से कम entropy sources इस्तेमाल करता हो तो मुझे निराशा होगी
यह तब होता है जब आप return value verify नहीं करते, जैसे पुराने Go में “N bytes माँगे थे, लेकिन सिर्फ़ 3 bytes मिले, इसलिए N-3 bytes फिर से माँगने चाहिए।” ज़्यादातर hardware या operating systems में यह आसानी से नहीं होता, इसलिए लोग चेक नहीं करते, और फिर एक दिन production में हज़ारों collisions के रूप में सामने आता है
throwaway_19sz: यक़ीन करना मुश्किल है, लेकिन यह सच है। 10 साल पहले मेरा एक दोस्त एक high-growth startup में CTO बना, कंपनी में लगभग 200 developers थे, और पहले ही हफ़्ते उसे पता चला कि वहाँ UUID generation के लिए dedicated microservice है
एक ही endpoint के लिए 3 dedicated engineers थे, यहाँ तक कि एक database admin भी था। जब भी किसी team को नया “safe” UUID चाहिए होता, उसे इसी service को call करना पड़ता। service UUID generate करती, फिर अपनी DB में देखती कि वही पहले से जारी तो नहीं हुआ, अगर नहीं तो insert करके वापस कर देती। शायद मानसिक शांति के लिए, उस team का अपना kanban board और sprint cycle भी चल रहा था
बाद में जिस startup में गया, वहाँ हर बार जब किसी को कोई नई चिंता सूझती, एक नई microservice और नई team पैदा हो जाती। quarterly goals में engineering team का size बढ़ाना साफ़ लिखा होता था, और 3-4 लोगों की teams अपने sprint और planning meetings में खुद अपने लिए काम बना लेती थीं। मैंने स्थिर project staffing को urgent work में shift करने का सुझाव दिया, लेकिन कहा गया कि वह headcount को एक तय संख्या तक बढ़ाने वाले KPI से टकराता है
high availability और global deployment के लिए sharding भी कर सकते हो: हर instance को dedicated ID range दे दो। कुछ higher bits data center ID के लिए reserve करो, और कुछ bits वहाँ के ID generator instance के लिए। ठहरो, यह कहीं देखा-सा लगता है… सोच रहा हूँ Twitter अब भी यही करता है या बाद में बदल दिया
हर दिन DB dump लिया जाता था ताकि “temporary” IDs generate करते समय verify किया जा सके, और CMDB में सही तरह submit होने के बाद ही वह “final” बनती थीं। temporary IDs production में इस्तेमाल न हों, इसके लिए guardrails भी थे, और unused final IDs को recycle करने की प्रक्रिया भी। आख़िरी बार सुना था कि local DB cache को Zookeeper पर ले जाने वाला 6 महीने का project 18वें महीने में चल रहा था
CodesInChaos: आम तौर पर यह खराब seed वाले pseudo-random generator की वजह से होता है। UUID backend पर बना या frontend पर, यह अहम है
frontend को मूल रूप से कई वजहों से भरोसेमंद नहीं माना जा सकता, जिनमें intentional collisions भी शामिल हैं, इसलिए collision handling ज़रूरी है। backend पर इसे भरोसेमंद तरीके से किया जा सकता है। पहले VM में यह समस्या थी, लेकिन अब तक तो इसे हल हो जाना चाहिए था। हालाँकि strongly sandboxed process अगर unsafe fallback random path इस्तेमाल करे तो अभी भी समस्या हो सकती है। process या VM fork भी state copy होने के कारण collisions पैदा कर सकते हैं
kst: “Pro Git” की एक पंक्ति याद आ गई। <https://git-scm.com/book/en/v2>
उदाहरण यह था कि अगर पृथ्वी पर मौजूद 6.5 अरब लोग हर सेकंड Linux kernel के पूरे history जितना code बनाकर एक विशाल Git repository में push करें, तब भी SHA-1 object collision की 50% संभावना तक पहुँचने में लगभग 2 साल लगेंगे। इसलिए natural SHA-1 collision की संभावना आपकी पूरी team के एक ही रात, एक-दूसरे से असंबंधित wolf attack में मारे जाने की संभावना से भी कम बताई गई थी। SHA-1 hash random number नहीं है और 160-bit है, इसलिए UUIDv4 से अलग है, लेकिन असंबंधित wolf attack वाली उपमा मुझे बहुत पसंद है
उपमा कुछ ऐसी है: अगर आप equator पर 1 अरब साल में एक क़दम चलते हुए पृथ्वी का चक्कर लगाएँ, हर चक्कर पर Pacific Ocean से एक बूँद पानी निकालें, और समुद्र खाली हो जाने के बाद एक कागज़ रख दें, और यह प्रक्रिया इतनी बार दोहराएँ कि ढेर सूरज तक पहुँच जाए, तब भी 52! सेकंड वाले timer के शुरुआती तीन अंक नहीं बदलेंगे
e12e: संबंधित चर्चा यहाँ है: https://github.com/uuidjs/uuid/issues/546
उदाहरण के लिए, इसमें कहा गया है कि
crypto.getRandomValues()को googlebot में test करने पर वह deterministic निकलाadyavanapalli: जो बात यहाँ कही जा रही है वह इतनी दुर्लभ है कि इस ठीक पल पूरी पृथ्वी के किसी asteroid से नष्ट हो जाने की संभावना शायद उससे ज़्यादा है
मैंने सुना था कि एक महिला वास्तव में meteorite से टकराई थी, लेकिन वह सिर्फ़ पैर की चोट के साथ बच गई। अगर UUID collision हुआ है, तो software bug या computer malfunction की संभावना बहुत ज़्यादा है, हालाँकि cosmic ray भी हो सकती है। memory या CPU पर cosmic ray का असर जितना लोग सोचते हैं, उससे अधिक आम है
juancn: क्या random generator initialization अजीब है या entropy कम है? अगर customize नहीं किया गया, तो यह
crypto.getRandomValues(rnds8)इस्तेमाल करता है, औरgetRandomValuesminimum entropy amount तय नहीं करताGeee: quantum mechanics की many-worlds interpretation के हिसाब से ऐसा कोई universe branch ज़रूर होगा जहाँ सारे UUID एक जैसे हों। सोचता हूँ वहाँ के लोग इसके बारे में क्या सोचते होंगे
mittermayr: मैं पूरी तरह सहमत हूँ कि यह बात समझ से बाहर है। फिर भी अगर अंदाज़ा लगाऊँ, तो फ़र्क यह हो सकता है कि पहले UUIDv4 user के phone पर generate होकर DB को भेजा जाता था, और आज सुबह टकराने वाला UUID Ubuntu server पर generate हुआ था
मुझे नहीं पता UUIDv4 असल में कैसे generate होता है, या generating machine की characteristics algorithm में जाती हैं या नहीं, लेकिन जो एक बदलाव सूझता है वह यही है कि पहले devices पर बनता था और कुछ महीनों से server पर बनने लगा है
लेकिन server पर, ख़ासकर 2026 में, ऐसा नहीं होना चाहिए। पहले VM random seed समस्या थी, लेकिन अब कम होनी चाहिए। फिर भी अगर एक UUID ख़राब तरीके से generate हुआ हो, तो सचमुच random UUID के उससे टकराने की संभावना बहुत कम है, इसलिए शायद दोनों generators में समस्या होनी चाहिए
dweez: इस मज़ेदार लेख को फिर से देखने का समय है: https://jasonfantl.com/posts/Universal-Unique-IDs/
अगर पूरे universe को एक विशाल computer में बदलकर heat death तक सिर्फ़ UUID generate किए जाएँ, तो ID space में कितने bits चाहिए होंगे?
beejiu: जिज्ञासा है कि UUID client side पर generate हो रहा है या server side पर। अगर client side पर है, तो crawler bot वजह हो सकता है। उदाहरण के लिए Googlebot JavaScript को deterministic “randomness” के साथ चलाता है
इस तरह की व्याख्याएँ सचमुच random collision की तुलना में कई orders of magnitude ज़्यादा plausible हैं
merlindru: seed issue होने की संभावना काफ़ी ज़्यादा है। अगर आप साबित कर दें कि ऐसा नहीं है, तो शायद थोड़ा मशहूर भी हो जाएँ
erlkonig: मैं हमेशा team से कहता आया हूँ कि अगर data काफ़ी हो तो random values कभी न कभी टकराएँगी, और तब पता चलेगा कि software कितना मज़बूत है
फिर भी अनुभवी developers, team leads, और CIOs में भी कई लोग इसे असंभव मानते हैं और ऐसी स्थिति से निपटने वाला code लिखते ही नहीं। तब कोई ख़राब random generator उम्मीद से कहीं पहले system को तोड़ सकता है, और detection या regeneration के बिना simultaneous corruption भी हो सकती है। यह मुझे उन लोगों जैसा लगता है जो
malloc()की success check नहीं करते। मैं अक्सर पूछता हूँ, “अगर यह असंभव है, तो क्या हम बहुत ज़्यादा bits इस्तेमाल नहीं कर रहे?”leni536: यह संयोग से नहीं हुआ, कहीं न कहीं bug है। ऊपर-ऊपर देखने पर package JS runtime के
crypto.randomUUID()को call करता दिखता है, और इसे हमेशा ठीक से seed होना चाहिएruntime bug की संभावना बेहद कम लगती है, लेकिन कौन जाने। जिज्ञासा है कि कौन-सा JS runtime इस्तेमाल हो रहा है
jbverschoor: सबसे plausible कारण यह है कि
uuidpackage जिस random generation package पर निर्भर करता है, वह हाल ही में compromise हुआ और “random” numbers को predictable बना दिया गया। नतीजतन supply-chain attack की वजह से कई cryptography, SSL, और currency projects भी जोखिम में आ गए होंगेuuid/src/rng.tsमें random array कोconstबना दिया गया था। इससे हर call वही random array share करने लगीबाद की calls पिछला random code overwrite कर देती हैं, इसलिए अगर आपने उससे कुछ महत्वपूर्ण generate किया हो तो शुभकामनाएँ। पुराना code
slice()से नई copy बनाता था। यह अनजाने में हुआ बदलाव हो सकता है, लेकिन समझ नहीं आता कि यह कैसे निकल गया, क्योंकि दो random values बनाकर यह जाँचने वाला test कि वे अलग हैं, शायद पास ही नहीं होताpif: high-quality entropy source होने पर भी “संभवतः ऐसा होगा” को “यह निश्चित ही होगा” में नहीं बदला जा सकता। अगर आपको ऐसा value चाहिए जिसे guess करना मुश्किल हो, तो cryptography की तरफ़ देखिए, लेकिन guaranteed uniqueness चाहिए तो उसे खुद बनाना होगा
athrowaway3z: एक आसान व्यावहारिक नियम है: सोचिए कि क्या ID में random value के अलावा timestamp जोड़ा जा सकता है। ज़्यादातर मामलों में जवाब हाँ होता है, और UUIDv7 काफ़ी है
अगर आपने यह सिद्ध कर लिया है कि information leakage स्वीकार्य नहीं है, तो बधाई। तब आपका system शायद इतना complex और धीमा है कि उसमें strong cryptographic hash इस्तेमाल होना चाहिए, या आसान रास्ते के लिए UUIDv5 भी चल सकता है
darqis: PostgreSQL 18 अब uuidv7 को native support देता है, और default को
uniqueतथाuuid7()पर सेट कर सकते हैंtumdum_: ख़राब seed वाला pseudo-random generator
serf: 4.72 × 10²⁸ में 1, यानी लगभग 47.3 octillion में 1। अगर यह सच है, तो lottery ticket खरीदने से पहले मैं race condition या दूसरी किसी साधारण गलती पर शक करूँगा
evnix: probability math को एक तरफ़ रख दें, तब भी जिस वास्तविक दुनिया में हम रहते हैं, वहाँ सबसे अच्छे hardware random generators भी हमारी सोच से कम random हो सकते हैं
जहाँ security critical नहीं है, वहाँ TSID जैसी चीज़ें, या uuidv7 पर जाना, व्यवहार में इस तरह की समस्या को लगभग खत्म कर देता है। मेरी नज़र में retry के लिए code को ज़रूरत से ज़्यादा architect करने से यह बेहतर है
jordiburgos:
b6133fd6-70fe-4fe3-bed6-8ca8fc9386cdकृपया मत इस्तेमाल करना। मैंने अपनी DB देखी, वह पहले से ही वहाँ इस्तेमाल हो रहा था16b55183-1697-496e-bc8a-854eb9aae0f3इस्तेमाल कर रहा हूँ, और शायद और भी हैं। अगर सब लोग यहाँ अपनी सूची डाल दें, तो क्या हम duplicates जाँच सकते हैं?pyuser583: आजकल preferred UUID कौन-सा माना जाता है, जानना चाहूँगा
smokel: कई बार compiler, cosmic ray, quantum effects, या कम-से-कम किसी obscure kernel bug को दोष देता रहा, और अंत में पता चला कि bug की जड़ मैं ही था
15,000 records में collision इतना दुर्लभ है कि मैं पहले दूसरे कारणों पर शक करूँगा। जैसे duplicate handling, retried request, reused object, भ्रामक logs, या किसी दूसरे code path में identifier का reuse। अगर आसपास का code थोड़ा और share करें तो साथ में देखना आसान होगा
wazoox: अभी तक मेरे साथ तो नहीं हुआ, लेकिन दो दिन पहले production में चल रहे एक PHP codebase की गहराई में यह मिला:
md5(uniqid('', true))से बनी value को काटकर UUID जैसा shape देने वालाcreateUUID()functionसमझ नहीं आता कि यह डरावनी चीज़ अभी तक आकर हमारी गर्दन कैसे नहीं काट गई
sedatk:
uuidjs/uuidमें चेतावनी है कि Googlebot जैसे deterministic random generator clients duplicate UUID generate कर सकते हैंजिन apps में client-generated UUID हमेशा unique होने की उम्मीद की जाती है, उनके लिए यह समस्या हो सकती है, इसलिए duplicates की जाँच, graceful failure, या Googlebot clients के write operations को disable करने जैसी strategy चाहिए: https://github.com/uuidjs/uuid/commit/91805f665c38b691ac2cbd...
xyzzy123: Linux-based distributed system में लंबे load test के दौरान duplicate UUID की वजह से failure हुआ था
लंबी जाँच के बाद पता चला कि यह kernel bug था, ख़ासकर race condition। multi-processor system में अगर दो processes एक साथ
/dev/randomपढ़ें, तो बहुत दुर्लभ स्थिति में, लगभग दस लाख में एक बार, उन्हें वही bytes मिल सकती थीं। मैं पहले random generator initialization देखूँगाbaq: लगता है running VM ने virtualization के चलते सारी entropy उड़ा दी
glaslong: कुछ lava lamps खरीदने का समय आ गया है
0xfffafaCrash: जिज्ञासा है कि UUID frontend पर generate हुआ था या backend पर। अगर frontend पर था, तो entropy issue से ज़्यादा मैं इस पर दाँव लगाऊँगा कि client code या request को tamper करके पहले से ज्ञात UUID inject किया गया हो
latentframe: engineering में सबसे ख़तरनाक वाक्यों में से एक है सांख्यिकीय रूप से असंभव। scale काफ़ी बड़ा हो जाए तो edge cases theory नहीं, production event बन जाते हैं
8organicbits: पिछले साल मैंने वास्तविक collision और उस library सहित इस पर एक लेख लिखा था: https://alexsci.com/blog/uuid-oops/
UUID के collision-resistant होने के लिए कई कठोर शर्तें पूरी करनी पड़ती हैं, और इस मामले में random generator में गड़बड़ी होने की संभावना अधिक लगती है
nu11ptr: आख़िरकार बात entropy source की ही है। इसलिए मैं हमेशा loop के अंदर generate और insert करता हूँ। collision हो तो उसे gracefully handle किया जा सकता है
sbuttgereit: यह “तकनीकी रूप से असंभव” नहीं है। तकनीकी रूप से तो पूरी तरह संभव है। अच्छी randomness हो तो बस बहुत, बहुत दुर्लभ होता है, और UUIDv4 को duplicate value बनाने से तकनीकी रूप से कुछ नहीं रोकता
beardyw: शायद यह बेवकूफ़ी भरा सवाल हो, लेकिन क्या इसमें date को, चाहे hexadecimal seconds के रूप में ही सही, जोड़ा नहीं जा सकता? कुछ bytes जोड़ देने से ऐसा लगता है कि जो आज ठीक है, वह भविष्य में भी ठीक रहेगा
mdavid626: दूसरी व्याख्या भी हो सकती है। उदाहरण के लिए किसी ने manually request बदल दी हो, या DB में छेड़छाड़ की हो
radial_symmetry: मेरे साथ भी एक बार ऐसा हुआ था और मुझे लगा था कि मैं पागल हो रहा हूँ, लेकिन यहाँ के comments पढ़कर राहत मिली
NKosmatos: यह “तकनीकी रूप से असंभव” नहीं है। असंभव नहीं, बस बहुत, बहुत दुर्लभ है। शायद lottery या Powerball खरीदना चाहिए
हर बार “improbable” शब्द सुनता हूँ तो https://hitchhikers.fandom.com/wiki/Infinite_Improbability_D... याद आ जाता है
sudb: मेरे एक project में CUID2 चुनना सचमुच अच्छा फ़ैसला था — यह महसूस होने का शायद पहला मौका है: https://github.com/paralleldrive/cuid2