diff --git a/cmd/tiller/release_server.go b/cmd/tiller/release_server.go
index 4dcb61a66c0e36f7ecb272cc17d7fe9cd6f8b062..0897853c920e5bff58a4738bcc7c16e68a64d9a0 100644
--- a/cmd/tiller/release_server.go
+++ b/cmd/tiller/release_server.go
@@ -278,12 +278,12 @@ func (s *releaseServer) UpdateRelease(c ctx.Context, req *services.UpdateRelease
 
 	res, err := s.performUpdate(currentRelease, updatedRelease, req)
 	if err != nil {
-		return nil, err
+		return res, err
 	}
 
 	if !req.DryRun {
 		if err := s.env.Releases.Create(updatedRelease); err != nil {
-			return nil, err
+			return res, err
 		}
 	}
 
@@ -306,7 +306,12 @@ func (s *releaseServer) performUpdate(originalRelease, updatedRelease *release.R
 	}
 
 	if err := s.performKubeUpdate(originalRelease, updatedRelease); err != nil {
-		return nil, err
+		log.Printf("warning: Release Upgrade %q failed: %s", updatedRelease.Name, err)
+		originalRelease.Info.Status.Code = release.Status_SUPERSEDED
+		updatedRelease.Info.Status.Code = release.Status_FAILED
+		s.recordRelease(originalRelease, true)
+		s.recordRelease(updatedRelease, false)
+		return res, err
 	}
 
 	// post-upgrade hooks
@@ -317,9 +322,7 @@ func (s *releaseServer) performUpdate(originalRelease, updatedRelease *release.R
 	}
 
 	originalRelease.Info.Status.Code = release.Status_SUPERSEDED
-	if err := s.env.Releases.Update(originalRelease); err != nil {
-		return nil, fmt.Errorf("Update of %s failed: %s", originalRelease.Name, err)
-	}
+	s.recordRelease(originalRelease, true)
 
 	updatedRelease.Info.Status.Code = release.Status_DEPLOYED
 
diff --git a/cmd/tiller/release_server_test.go b/cmd/tiller/release_server_test.go
index d63a52e42e598cb93407782cd1d5b451d79932b6..72b054c20e8a6e2a1b1c74a8df1c6266f0783455 100644
--- a/cmd/tiller/release_server_test.go
+++ b/cmd/tiller/release_server_test.go
@@ -587,6 +587,42 @@ func TestUpdateRelease(t *testing.T) {
 	}
 }
 
+func TestUpdateReleaseFailure(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+	rel := releaseStub()
+	rs.env.Releases.Create(rel)
+	rs.env.KubeClient = newUpdateFailingKubeClient()
+
+	req := &services.UpdateReleaseRequest{
+		Name:         rel.Name,
+		DisableHooks: true,
+		Chart: &chart.Chart{
+			Metadata: &chart.Metadata{Name: "hello"},
+			Templates: []*chart.Template{
+				{Name: "something", Data: []byte("hello: world")},
+			},
+		},
+	}
+
+	res, err := rs.UpdateRelease(c, req)
+	if err == nil {
+		t.Error("Expected failed update")
+	}
+
+	if updatedStatus := res.Release.Info.Status.Code; updatedStatus != release.Status_FAILED {
+		t.Errorf("Expected FAILED release. Got %d", updatedStatus)
+	}
+
+	oldRelease, err := rs.env.Releases.Get(rel.Name, rel.Version)
+	if err != nil {
+		t.Errorf("Expected to be able to get previous release")
+	}
+	if oldStatus := oldRelease.Info.Status.Code; oldStatus != release.Status_SUPERSEDED {
+		t.Errorf("Expected SUPERSEDED status on previous Release version. Got %v", oldStatus)
+	}
+}
+
 func TestUpdateReleaseNoHooks(t *testing.T) {
 	c := helm.NewContext()
 	rs := rsFixture()
@@ -1136,6 +1172,21 @@ func mockEnvironment() *environment.Environment {
 	return e
 }
 
+func newUpdateFailingKubeClient() *updateFailingKubeClient {
+	return &updateFailingKubeClient{
+		PrintingKubeClient: environment.PrintingKubeClient{Out: os.Stdout},
+	}
+
+}
+
+type updateFailingKubeClient struct {
+	environment.PrintingKubeClient
+}
+
+func (u *updateFailingKubeClient) Update(namespace string, originalReader, modifiedReader io.Reader) error {
+	return errors.New("Failed update in kube client")
+}
+
 func newHookFailingKubeClient() *hookFailingKubeClient {
 	return &hookFailingKubeClient{
 		PrintingKubeClient: environment.PrintingKubeClient{Out: os.Stdout},