diff --git a/ctrl/text.dat b/ctrl/text.dat
index c25bfdbdd136af691f2266d4e6f86d6c3dd79d53..580967e52caac1f7ed275871172881307564b566 100644
--- a/ctrl/text.dat
+++ b/ctrl/text.dat
@@ -255,7 +255,7 @@
 "\r\n\1r\1h\1iThat file is not on disk!\1n\r\n"             209 FileNotOnDisk
 "\r\n\1r\1h\1iPlease upload files with the following "\    210 TheseFileExtsOnly
 	"extensions only:\1n\r\n\1w\1h"
-"\r\n\1r\1h\1i%s has already been uploaded!\1n\r\n"         211 FileAlreadyOnline
+"\r\n\1n\1h%s\1r\1h\1i has already been uploaded to\1n\1c %s \1h%s\1n\r\n" 211 FileAlreadyOnline
 "\r\n\1w\1hHit [ENTER] after last destination "\          212 EnterAfterLastDestUser
 	"user.\r\n\r\n"
 "\1_\1y\1hSend file to (User name or number): \1n"          213 SendFileToUser
diff --git a/src/sbbs3/bat_xfer.cpp b/src/sbbs3/bat_xfer.cpp
index 623e78124372247ad68921bf25f35c810f36e64a..b69b2d912da3da56c31ce2e5ef9f918fa2dc9056 100644
--- a/src/sbbs3/bat_xfer.cpp
+++ b/src/sbbs3/bat_xfer.cpp
@@ -548,7 +548,7 @@ void sbbs_t::batch_upload()
 		SAFEPRINTF2(src, "%s%s", cfg.temp_dir, filename);
 		SAFEPRINTF2(dest, "%s%s", cfg.dir[dir]->path, filename);
 		if(fexistcase(src) && fexistcase(dest)) { /* file's in two places */
-			bprintf(text[FileAlreadyThere], filename);
+			bprintf(text[FileAlreadyOnline], filename, lib_name(dir), dir_name(dir));
 			remove(src);    /* this is the one received */
 			continue;
 		}
@@ -581,7 +581,9 @@ void sbbs_t::batch_upload()
 		}
 		SAFEPRINTF2(dest, "%s%s", cfg.dir[cfg.upload_dir]->path, dirent->d_name);
 		if(fexistcase(dest)) {
-			bprintf(text[FileAlreadyOnline], dirent->d_name);
+			bprintf(text[FileAlreadyOnline], dirent->d_name
+				,lib_name(cfg.upload_dir)
+				,dir_name(cfg.upload_dir));
 			continue;
 		}
 		if(mv(src, dest, /* copy: */false))
@@ -599,7 +601,8 @@ void sbbs_t::batch_upload()
 		}
 		bputs(text[SearchedForDupes]);
 		if(x<usrlibs) {
-			bprintf(text[FileAlreadyOnline], dirent->d_name);
+			bprintf(text[FileAlreadyOnline], dirent->d_name
+				,lib_name(usrdir[x][y]), dir_name(usrdir[x][y]));
 		} else {
 			file_t f = {{}};
 			f.dir = cfg.upload_dir;
diff --git a/src/sbbs3/file.cpp b/src/sbbs3/file.cpp
index 35b63fca0ce8122845bf2a824eb180f85e641ac0..449a7ebc229259a85937d03d85b1f30749adbbb4 100644
--- a/src/sbbs3/file.cpp
+++ b/src/sbbs3/file.cpp
@@ -234,7 +234,7 @@ bool sbbs_t::movefile(smb_t* smb, file_t* f, int newdir)
 {
 	file_t newfile = *f;
 	if(findfile(&cfg, newdir, f->name, NULL)) {
-		bprintf(text[FileAlreadyThere], f->name);
+		bprintf(text[FileAlreadyOnline], f->name, lib_name(newdir), dir_name(newdir));
 		return false;
 	}
 
diff --git a/src/sbbs3/text_defaults.c b/src/sbbs3/text_defaults.c
index 4b7f363ca577c5bd4b04c870147c9850e12a3cd1..8a2c7c219b8eb88bea3d66a1ce642870c139538c 100644
--- a/src/sbbs3/text_defaults.c
+++ b/src/sbbs3/text_defaults.c
@@ -346,8 +346,8 @@ const char * const text_defaults[TOTAL_TEXT]={
 	,"\x0d\x0a\x01\x72\x01\x68\x01\x69\x50\x6c\x65\x61\x73\x65\x20\x75\x70\x6c\x6f\x61\x64\x20\x66\x69\x6c\x65\x73\x20\x77\x69\x74\x68"
 		"\x20\x74\x68\x65\x20\x66\x6f\x6c\x6c\x6f\x77\x69\x6e\x67\x20\x65\x78\x74\x65\x6e\x73\x69\x6f\x6e\x73\x20\x6f\x6e\x6c\x79\x3a\x01"
 		"\x6e\x0d\x0a\x01\x77\x01\x68" // 210 TheseFileExtsOnly
-	,"\x0d\x0a\x01\x72\x01\x68\x01\x69\x25\x73\x20\x68\x61\x73\x20\x61\x6c\x72\x65\x61\x64\x79\x20\x62\x65\x65\x6e\x20\x75\x70\x6c\x6f"
-		"\x61\x64\x65\x64\x21\x01\x6e\x0d\x0a" // 211 FileAlreadyOnline
+	,"\x0d\x0a\x01\x6e\x01\x68\x25\x73\x01\x72\x01\x68\x01\x69\x20\x68\x61\x73\x20\x61\x6c\x72\x65\x61\x64\x79\x20\x62\x65\x65\x6e\x20"
+		"\x75\x70\x6c\x6f\x61\x64\x65\x64\x20\x74\x6f\x01\x6e\x01\x63\x20\x25\x73\x20\x01\x68\x25\x73\x01\x6e\x0d\x0a" // 211 FileAlreadyOnline
 	,"\x0d\x0a\x01\x77\x01\x68\x48\x69\x74\x20\x5b\x45\x4e\x54\x45\x52\x5d\x20\x61\x66\x74\x65\x72\x20\x6c\x61\x73\x74\x20\x64\x65\x73"
 		"\x74\x69\x6e\x61\x74\x69\x6f\x6e\x20\x75\x73\x65\x72\x2e\x0d\x0a\x0d\x0a" // 212 EnterAfterLastDestUser
 	,"\x01\x5f\x01\x79\x01\x68\x53\x65\x6e\x64\x20\x66\x69\x6c\x65\x20\x74\x6f\x20\x28\x55\x73\x65\x72\x20\x6e\x61\x6d\x65\x20\x6f\x72"
diff --git a/src/sbbs3/upload.cpp b/src/sbbs3/upload.cpp
index 406a2c1c39289e87d6c3a82f3e64aab80c51d066..232aab3d063dcad819d303c449720b06256d863b 100644
--- a/src/sbbs3/upload.cpp
+++ b/src/sbbs3/upload.cpp
@@ -125,7 +125,7 @@ bool sbbs_t::uploadfile(file_t* f)
 			for(int j=0; j < usrdirs[i]; j++,k++) {
 				if(cfg.dir[usrdir[i][j]]->misc&DIR_DUPES
 					&& findfile(&cfg, usrdir[i][j], /* filename: */NULL, f)) {
-					bprintf(text[FileAlreadyOnline], f->name);
+					bprintf(text[FileAlreadyOnline], f->name, lib_name(usrdir[i][j]), dir_name(usrdir[i][j]));
 					if(!dir_op(f->dir)) {
 						remove(path);
 						safe_snprintf(str, sizeof(str), "attempted to upload %s to %s %s (duplicate hash)"
@@ -315,7 +315,7 @@ bool sbbs_t::upload(int dirnum)
 	bool found = findfile(&cfg, dirnum, fname, NULL);
 	bputs(text[SearchedForDupes]);
 	if(found) {
-		bprintf(text[FileAlreadyOnline],fname);
+		bprintf(text[FileAlreadyOnline],fname, lib_name(dirnum), dir_name(dirnum));
 		return(false); 	 /* File is already in database */
 	}
 	for(i=k=0;i<usrlibs;i++) {
@@ -326,7 +326,7 @@ bool sbbs_t::upload(int dirnum)
 			if(cfg.dir[usrdir[i][j]]->misc&DIR_DUPES
 				&& findfile(&cfg, usrdir[i][j], fname, NULL)) {
 				bputs(text[SearchedForDupes]);
-				bprintf(text[FileAlreadyOnline],fname);
+				bprintf(text[FileAlreadyOnline], fname, lib_name(usrdir[i][j]), dir_name(usrdir[i][j]));
 				if(!dir_op(dirnum))
 					return(false); 	 /* File is in database for another dir */
 			}