Description of problem: This bug has been around since the beginning of time. Actually not really, but since very early versions of rpm where the split of dirnames and basenames was introduced. The way rpm generates dirnames for a build is simply put like this (in pseudocode): Generate filelist with dirs Sort filelist for each file in filelist: Split dname and bname from file Search dirindex for dname in dirnames using glibc bsearch if found, use dirindex for that bname otherwise append dname to dirnames and use new dirindex for that bname append bname to basenames Now on first glance this sounds correct. But if you look closely at how the filelist is generated you'll suddenly see that dirnames afterwards isn't actually a sorted list. Here a real life example of glibc-common.i386 from Fedora-9 release (glibc-common-2.8-3.i386.rpm) Output of rpm -qpl glibc-common-2.8-3.i386.rpm: /etc/default /etc/default/nss /usr/bin/catchsegv /usr/bin/gencat /usr/bin/getconf /usr/bin/getent /usr/bin/iconv /usr/bin/ldd /usr/bin/lddlibc4 /usr/bin/locale /usr/bin/localedef /usr/bin/rpcgen /usr/bin/sprof /usr/bin/tzselect /usr/lib/locale /usr/lib/locale/locale-archive /usr/lib/locale/locale-archive.tmpl /usr/libexec/pt_chown /usr/sbin/build-locale-archive /usr/sbin/tzdata-update /usr/sbin/zdump /usr/sbin/zic /usr/share/doc/glibc-common-2.8 /usr/share/doc/glibc-common-2.8/ChangeLog.15.bz2 /usr/share/doc/glibc-common-2.8/ChangeLog.16.bz2 /usr/share/doc/glibc-common-2.8/ChangeLog.bz2 /usr/share/doc/glibc-common-2.8/README.timezone /usr/share/doc/glibc-common-2.8/README.ufc-crypt /usr/share/doc/glibc-common-2.8/gai.conf /usr/share/i18n /usr/share/i18n/charmaps /usr/share/i18n/charmaps/ANSI_X3.110-1983.gz /usr/share/i18n/charmaps/ANSI_X3.4-1968.gz ... /usr/share/i18n/charmaps/UTF-8.gz /usr/share/i18n/charmaps/VIDEOTEX-SUPPL.gz /usr/share/i18n/charmaps/VISCII.gz /usr/share/i18n/charmaps/WINDOWS-31J.gz /usr/share/i18n/locales /usr/share/i18n/locales/POSIX /usr/share/i18n/locales/aa_DJ ... /usr/share/i18n/locales/zh_SG /usr/share/i18n/locales/zh_TW /usr/share/i18n/locales/zu_ZA /usr/share/locale /usr/share/locale/be /usr/share/locale/be/LC_MESSAGES /usr/share/locale/be/LC_MESSAGES/libc.mo /usr/share/locale/bg /usr/share/locale/bg/LC_MESSAGES /usr/share/locale/bg/LC_MESSAGES/libc.mo /usr/share/locale/ca Side by side comparison of dirnames and LANG=C sorted dirnames: /etc/ /etc/ /etc/default/ /etc/default/ /usr/bin/ /usr/bin/ /usr/lib/ /usr/lib/ /usr/lib/locale/ /usr/lib/locale/ /usr/libexec/ /usr/libexec/ /usr/sbin/ /usr/sbin/ /usr/share/doc/ /usr/share/ /usr/share/doc/glibc-common-2.8/ /usr/share/ /usr/share/ /usr/share/doc/ /usr/share/i18n/ /usr/share/doc/glibc-common-2.8/ /usr/share/i18n/charmaps/ /usr/share/i18n/ /usr/share/i18n/locales/ /usr/share/i18n/charmaps/ /usr/share/ /usr/share/i18n/locales/ /usr/share/locale/ /usr/share/locale/ As you can see, /usr/share/ is listed twice in the dirnames list. This comes from the simple fact that after the splitting of dirnames and basenames for the files the resulting dirnames aren't sorted anymore: ... /usr/share/doc/glibc-common-2.8 -> /usr/share/doc/ : glibc-common-2.8 ... /usr/share/i18n -> /usr/share/ : i18n ... /usr/share/i18n/charmaps -> /usr/share/i18n/ : charmaps ... /usr/share/i18n/charmaps/ANSI_X3.110-1983.gz -> /usr/share/i18n/charmaps/ : ANSI_X3.110-1983.gz ... /usr/share/i18n/locales -> /usr/share/i18n/ : locales ... /usr/share/i18n/locales/POSIX -> /usr/share/i18n/locales/ : POSIX ... /usr/share/locale -> /usr/share/ : locale ... /usr/share/locale/be -> /usr/share/locale/ : be And as that list isn't sorted anymore it comes as no surprise that bsearch() will eventually not find an already existing dirname in dirnames, e.g. /usr/share/ in this example. This has several obvious problems: - Duplicate dirname entries in dirnames, wasting space - If the bsearch() implementation of glibc should ever change you will get different dirnames headers for idential filelists - Any tool working with rpm headers and dirnames that assumes that dirnames is sorted and/or unique will fail miserably Version-Release number of selected component (if applicable): rpm since the change from "filenames" tag to "dirnames" and "basenames". How reproducible: Happens with lots of rpms with larger filelists. A correct implementation would probably have to do use 2 pass algorithm to first collect a list of all possible dirnames and then uniquely sort it and in the 2nd pass extract the basenames and use the now correctly working bsearch() for any implementation to find the corresponding dirname from dirnames. Thanks & regards, Phil