diff --git a/__tests__/src/components/ManifestListItemError.test.js b/__tests__/src/components/ManifestListItemError.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..9606b3de0e3ed051f716e3d8c7d736edfd2dd416
--- /dev/null
+++ b/__tests__/src/components/ManifestListItemError.test.js
@@ -0,0 +1,54 @@
+import React from 'react';
+import { shallow } from 'enzyme';
+import Typography from '@material-ui/core/Typography';
+import ManifestListItemError from '../../../src/components/ManifestListItemError';
+
+/**
+ * Helper function to wrap creating a ManifestListItemError component
+*/
+function createWrapper(props) {
+  return shallow(
+    <ManifestListItemError
+      manifestId="http://example.com"
+      onDismissClick={() => {}}
+      onTryAgainClick={() => {}}
+      t={key => key}
+      {...props}
+    />,
+  ).dive(); // unwrap HOC created by withStyles()
+}
+
+describe('ManifestListItemError', () => {
+  let wrapper;
+  let mockFn;
+
+  it('renders the failed manifest url and error key', () => {
+    wrapper = createWrapper();
+
+    expect(
+      wrapper.find(Typography).children().first().text(),
+    ).toEqual('manifestError'); // the i18n key
+
+    expect(
+      wrapper.find(Typography).children().last().text(),
+    ).toEqual('http://example.com');
+  });
+
+  it('has a dismiss button that fires the onDismissClick prop', () => {
+    mockFn = jest.fn();
+    wrapper = createWrapper({ onDismissClick: mockFn });
+
+    wrapper.find('WithStyles(Button)').first().simulate('click');
+    expect(mockFn).toHaveBeenCalledTimes(1);
+    expect(mockFn).toHaveBeenCalledWith('http://example.com');
+  });
+
+  it('has a try again button that fires the onTryAgainClick prop', () => {
+    mockFn = jest.fn();
+    wrapper = createWrapper({ onTryAgainClick: mockFn });
+
+    wrapper.find('WithStyles(Button)').last().simulate('click');
+    expect(mockFn).toHaveBeenCalledTimes(1);
+    expect(mockFn).toHaveBeenCalledWith('http://example.com');
+  });
+});
diff --git a/locales/en/translation.json b/locales/en/translation.json
index cccb1a7cd96c16732278976805381d66fcbebc24..2b316ec58f400c10823d9c1105cc405e566832e1 100644
--- a/locales/en/translation.json
+++ b/locales/en/translation.json
@@ -16,12 +16,14 @@
     "closeMenu": "Close Menu",
     "closeWindow": "Close window",
     "dark": "Dark",
+    "dismiss": "Dismiss",
     "downloadExport": "Download/Export",
     "downloadExportWorkspace": "Download/export workspace",
     "fetchManifest": "Add",
     "fullScreen": "Full Screen",
     "light": "Light",
     "listAllOpenWindows": "List all open windows",
+    "manifestError": "The resource cannot be added:",
     "menu": "Menu",
     "off": "Off",
     "openInfoCompanionWindow": "Open information companion window",
@@ -35,6 +37,7 @@
     "theme": "Theme",
     "thumbnails": "Thumbnails",
     "toggleWindowSideBar": "Toggle window sidebar",
+    "tryAgain": "Try again",
     "untitled": "[Untitled]",
     "view": "View",
     "zoomIn": "Zoom in",
diff --git a/src/components/ManifestListItemError.js b/src/components/ManifestListItemError.js
new file mode 100644
index 0000000000000000000000000000000000000000..2d4c82df387012d7ac2c3317205fb9817ebd16e6
--- /dev/null
+++ b/src/components/ManifestListItemError.js
@@ -0,0 +1,79 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import Button from '@material-ui/core/Button';
+import ErrorIcon from '@material-ui/icons/ErrorOutline';
+import Grid from '@material-ui/core/Grid';
+import Typography from '@material-ui/core/Typography';
+import { withStyles } from '@material-ui/core/styles';
+
+/**
+ * ManifestListItemError renders a component displaying a
+ * message to the user about a problem loading a manifest
+*/
+class ManifestListItemError extends Component {
+  /**
+   * Returns the rendered component
+  */
+  render() {
+    const {
+      classes, manifestId, onDismissClick, onTryAgainClick, t,
+    } = this.props;
+
+    return (
+      <Grid container>
+        <Grid container>
+          <Grid container item xs={12} sm={6}>
+            <Grid item xs={4} sm={3}>
+              <Grid container justify="center">
+                <ErrorIcon className={classes.errorIcon} />
+              </Grid>
+            </Grid>
+            <Grid item xs={8} sm={9}>
+              <Typography>{t('manifestError')}</Typography>
+              <Typography className={classes.manifestIdText}>{manifestId}</Typography>
+            </Grid>
+          </Grid>
+        </Grid>
+
+        <Grid container>
+          <Grid container item xs={12} sm={6} justify="flex-end">
+            <Grid item>
+              <Button onClick={() => { onDismissClick(manifestId); }}>
+                {t('dismiss')}
+              </Button>
+              <Button onClick={() => { onTryAgainClick(manifestId); }}>
+                {t('tryAgain')}
+              </Button>
+            </Grid>
+          </Grid>
+        </Grid>
+      </Grid>
+    );
+  }
+}
+
+
+ManifestListItemError.propTypes = {
+  classes: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
+  manifestId: PropTypes.string.isRequired,
+  onDismissClick: PropTypes.func.isRequired,
+  onTryAgainClick: PropTypes.func.isRequired,
+  t: PropTypes.func.isRequired,
+};
+
+/**
+ Material UI styles
+ @private
+ */
+const styles = theme => ({
+  errorIcon: {
+    color: theme.palette.error.main,
+    height: '2rem',
+    width: '2rem',
+  },
+  manifestIdText: {
+    wordBreak: 'break-all',
+  },
+});
+
+export default withStyles(styles)(ManifestListItemError);
diff --git a/src/containers/ManifestListItemError.js b/src/containers/ManifestListItemError.js
new file mode 100644
index 0000000000000000000000000000000000000000..237c17f9b5a3048ec1db3f1e3d8e6bdf264c6c01
--- /dev/null
+++ b/src/containers/ManifestListItemError.js
@@ -0,0 +1,19 @@
+import { compose } from 'redux';
+import { connect } from 'react-redux';
+import { withNamespaces } from 'react-i18next';
+import { fetchManifest, removeManifest } from '../state/actions/manifest';
+import ManifestListItemError from '../components/ManifestListItemError';
+
+/** */
+const mapDispatchToProps = {
+  onDismissClick: removeManifest,
+  onTryAgainClick: fetchManifest,
+};
+
+const enhance = compose(
+  connect(null, mapDispatchToProps),
+  withNamespaces(),
+  // further HOC
+);
+
+export default enhance(ManifestListItemError);