diff --git a/README.md b/README.md
index d576747..27881df 100644
--- a/README.md
+++ b/README.md
@@ -203,7 +203,32 @@ Environment variables along with context expressions can also be used for input.
 In the top right corner of a workflow run, once the run is over, if you used this action, there will be a `Artifacts` dropdown which you can download items from. Here's a screenshot of what it looks like<br/>
 <img src="https://user-images.githubusercontent.com/16109154/72556687-20235a80-386d-11ea-9e2a-b534faa77083.png" width="375" height="140">
 
-There is a trashcan icon that can be used to delete the artifact. This icon will only appear for users who have write permissions to the repository. 
+There is a trashcan icon that can be used to delete the artifact. This icon will only appear for users who have write permissions to the repository.
+
+# Limitations
+
+### Permission Loss
+
+:exclamation: File permissions are not maintained during artifact upload :exclamation: For example, if you make a file executable using `chmod` and then upload that file, post-download the file is no longer guaranteed to be set as an executable.
+
+### Case Insensitive Uploads
+
+:exclamation: File uploads are case insensitive :exclamation: If you upload `A.txt` and `a.txt` with the same root path, only a single file will be saved and available during download.
+
+### Maintaining file permissions and case sensitive files
+
+If file permissions and case sensitivity are required, you can `tar` all of your files together before artifact upload. Post download, the `tar` file will maintain file permissions and case sensitivity.
+
+```yaml
+  - name: 'Tar files'
+    run: tar -cvf my_files.tar /path/to/my/directory
+
+  - name: 'Upload Artifact'
+    uses: actions/upload-artifact@v2
+    with:
+      name: my-artifact
+      path: my_files.tar    
+```
 
 ## Additional Documentation
 
diff --git a/dist/index.js b/dist/index.js
index e9321ce..264f2de 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -4992,11 +4992,12 @@ const utils_1 = __webpack_require__(870);
  * Used for managing http clients during either upload or download
  */
 class HttpManager {
-    constructor(clientCount) {
+    constructor(clientCount, userAgent) {
         if (clientCount < 1) {
             throw new Error('There must be at least one client');
         }
-        this.clients = new Array(clientCount).fill(utils_1.createHttpClient());
+        this.userAgent = userAgent;
+        this.clients = new Array(clientCount).fill(utils_1.createHttpClient(userAgent));
     }
     getClient(index) {
         return this.clients[index];
@@ -5005,7 +5006,7 @@ class HttpManager {
     // for more information see: https://github.com/actions/http-client/blob/04e5ad73cd3fd1f5610a32116b0759eddf6570d2/index.ts#L292
     disposeAndReplaceClient(index) {
         this.clients[index].dispose();
-        this.clients[index] = utils_1.createHttpClient();
+        this.clients[index] = utils_1.createHttpClient(this.userAgent);
     }
     disposeAndReplaceAllClients() {
         for (const [index] of this.clients.entries()) {
@@ -6288,7 +6289,7 @@ function getMultiPathLCA(searchPaths) {
         }
         return true;
     }
-    // Loop over all the search paths until there is a non-common ancestor or we go out of bounds
+    // loop over all the search paths until there is a non-common ancestor or we go out of bounds
     while (splitIndex < smallestPathLength) {
         if (!isPathTheSame()) {
             break;
@@ -6304,6 +6305,11 @@ function findFilesToUpload(searchPath, globOptions) {
         const searchResults = [];
         const globber = yield glob.create(searchPath, globOptions || getDefaultGlobOptions());
         const rawSearchResults = yield globber.glob();
+        /*
+          Files are saved with case insensitivity. Uploading both a.txt and A.txt will files to be overwritten
+          Detect any files that could be overwritten for user awareness
+        */
+        const set = new Set();
         /*
           Directories will be rejected if attempted to be uploaded. This includes just empty
           directories so filter any directories out from the raw search results
@@ -6314,6 +6320,13 @@ function findFilesToUpload(searchPath, globOptions) {
             if (!fileStats.isDirectory()) {
                 core_1.debug(`File:${searchResult} was found using the provided searchPath`);
                 searchResults.push(searchResult);
+                // detect any files that would be overwritten because of case insensitivity
+                if (set.has(searchResult.toLowerCase())) {
+                    core_1.info(`Uploads are case insensitive: ${searchResult} was detected that it will be overwritten by another file with the same path`);
+                }
+                else {
+                    set.add(searchResult.toLowerCase());
+                }
             }
             else {
                 core_1.debug(`Removing ${searchResult} from rawSearchResults because it is a directory`);
@@ -6645,7 +6658,7 @@ const upload_gzip_1 = __webpack_require__(647);
 const stat = util_1.promisify(fs.stat);
 class UploadHttpClient {
     constructor() {
-        this.uploadHttpManager = new http_manager_1.HttpManager(config_variables_1.getUploadFileConcurrency());
+        this.uploadHttpManager = new http_manager_1.HttpManager(config_variables_1.getUploadFileConcurrency(), 'actions/upload-artifact');
         this.statusReporter = new status_reporter_1.StatusReporter(10000);
     }
     /**
@@ -7399,7 +7412,7 @@ const http_manager_1 = __webpack_require__(452);
 const config_variables_1 = __webpack_require__(401);
 class DownloadHttpClient {
     constructor() {
-        this.downloadHttpManager = new http_manager_1.HttpManager(config_variables_1.getDownloadFileConcurrency());
+        this.downloadHttpManager = new http_manager_1.HttpManager(config_variables_1.getDownloadFileConcurrency(), 'actions/download-artifact');
         // downloads are usually significantly faster than uploads so display status information every second
         this.statusReporter = new status_reporter_1.StatusReporter(1000);
     }
@@ -8034,8 +8047,8 @@ function getUploadHeaders(contentType, isKeepAlive, isGzip, uncompressedLength,
     return requestOptions;
 }
 exports.getUploadHeaders = getUploadHeaders;
-function createHttpClient() {
-    return new http_client_1.HttpClient('actions/artifact', [
+function createHttpClient(userAgent) {
+    return new http_client_1.HttpClient(userAgent, [
         new auth_1.BearerCredentialHandler(config_variables_1.getRuntimeToken())
     ]);
 }
diff --git a/package-lock.json b/package-lock.json
index 61facf7..e789485 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5,9 +5,9 @@
   "requires": true,
   "dependencies": {
     "@actions/artifact": {
-      "version": "0.3.2",
-      "resolved": "https://registry.npmjs.org/@actions/artifact/-/artifact-0.3.2.tgz",
-      "integrity": "sha512-KzUe5DEeVXprAodxfGKtx9f7ukuVKE6V6pge6t5GDGk0cdkfiMEfahoq7HfBsOsmVy4J7rr1YZQPUTvXveYinw==",
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/@actions/artifact/-/artifact-0.3.3.tgz",
+      "integrity": "sha512-sKC1uA5p6064C6Qypmmt6O8iKlpDyMTfqqDlS4/zfJX1Hs8NbbzPLLN81RpewuJPWQNnroeF52w4VCWypbSNaA==",
       "dev": true,
       "requires": {
         "@actions/core": "^1.2.1",
diff --git a/package.json b/package.json
index e13d64c..12511ee 100644
--- a/package.json
+++ b/package.json
@@ -29,7 +29,7 @@
   },
   "homepage": "https://github.com/actions/upload-artifact#readme",
   "devDependencies": {
-    "@actions/artifact": "^0.3.2",
+    "@actions/artifact": "^0.3.3",
     "@actions/core": "^1.2.3",
     "@actions/glob": "^0.1.0",
     "@actions/io": "^1.0.2",
diff --git a/src/search.ts b/src/search.ts
index 5a4911a..bd80164 100644
--- a/src/search.ts
+++ b/src/search.ts
@@ -66,7 +66,7 @@ function getMultiPathLCA(searchPaths: string[]): string {
     return true
   }
 
-  // Loop over all the search paths until there is a non-common ancestor or we go out of bounds
+  // loop over all the search paths until there is a non-common ancestor or we go out of bounds
   while (splitIndex < smallestPathLength) {
     if (!isPathTheSame()) {
       break
@@ -89,6 +89,12 @@ export async function findFilesToUpload(
   )
   const rawSearchResults: string[] = await globber.glob()
 
+  /*
+    Files are saved with case insensitivity. Uploading both a.txt and A.txt will files to be overwritten
+    Detect any files that could be overwritten for user awareness
+  */
+  const set = new Set<string>()
+
   /*
     Directories will be rejected if attempted to be uploaded. This includes just empty
     directories so filter any directories out from the raw search results
@@ -99,6 +105,15 @@ export async function findFilesToUpload(
     if (!fileStats.isDirectory()) {
       debug(`File:${searchResult} was found using the provided searchPath`)
       searchResults.push(searchResult)
+
+      // detect any files that would be overwritten because of case insensitivity
+      if (set.has(searchResult.toLowerCase())) {
+        info(
+          `Uploads are case insensitive: ${searchResult} was detected that it will be overwritten by another file with the same path`
+        )
+      } else {
+        set.add(searchResult.toLowerCase())
+      }
     } else {
       debug(
         `Removing ${searchResult} from rawSearchResults because it is a directory`